perm filename RSK10.FAI[SS,SYS] blob sn#731139 filedate 1983-11-13 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00041 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00010 00002	 DEBSW DSKDSW DSKDBG KLBOOT RHDSK FT1DSK EXTNEW KACODE NPACKS EXTNEW DEBSW DSKDBG F A B C D E H J K L M N T TT P HILOC NUFDWD RBO CUADR APR PI KLPAG CCA TTY C1A C1B RH0 DTE0 DTFLG DTF11 DTCMD DONG11 SWEEPB PIOFF DSTART KLEPT
C00019 00003	PTPC PTR PNCHGO GO1 GO2 PUNCHC PUNCH RIMLDR RIMLDL RIMPDL OBUF BOOTLO BOOTBG XBUF XBUF BOOTBG XBUF
C00025 00004	C1SBI C1RSI C1SRUN C1CONT C1SCH C1RST C1CCIF C1INTE C1INTD C1SCF1 C1CCF1 C1MPCN C1LCD C1LPT C1SYSR C1SCAN C1SDIA CIF CF1 CF2 C1UCHK
C00030 00005	C1CMD C1MRT C1JMP C1TIO C1IWC C1BAK C1NATM C1BYTM C1CBYT C1SLE C1CEC C1NOC C1RPT C1CCW C1ISW C1PTPE C1PTNX C1IQF C1PPTR C1PCW C1BW C1STA C1HLT C1LE C1SE C1PE C1NXM C1BPE C1SSE C1PCMA C1STB C1STC C1INST
C00036 00006	MFDLOC TRKCYL CYLPK TRKPK NXTQQQ A NXTQQQ NXTQQQ
C00041 00007	DSKDMP.DMP FORMAT
C00045 00008	LOWEST BOOT BOOT1 BOOTL1 BOOTL2 BOOTL3 NODSKD NOSYS  LOWEST BOOT BOOT1 BOOTL1 BOOTL2 BOOTL3 NOMFD NODSKD NOSYS NOMFD0
C00053 00009	LOWEST DSKDMP DSKDM0 DSKDM1 DSKDM2 DSKDL DSKDL2 DSKDL1 DSKDRO DSKDAL DSKAL1 QQQ DSKDGO CMDS NCMDS CMDDSP SSTRTA SSTRT1 SSTRT2 START LOADGO NOMUCK MERGE LOAD LOADN LOADIT LDIT0 LDIT0A LDIT1 LDIT3 LDIT4 LDIT2 LDLP LDLP1 LDLP3 FILES DUMP KILL NSA FNF
C00069 00010	 FILSET FILSE0 FILSE1 FILSIX FILSI1 RADJ RADJ1
C00074 00011	 FNDMFD SRCH SRCH1 SRCH2 SRCH3 SRCHLP SRCH5 SRCH4 RDRET READ READ0 READC1 C1WAIT C1WAIA C1WAIB C1WERR C1DIE C1MPIL C1MPI1 C1SET BLAST RSTC1
C00085 00012	TYPE TYPE1 TYO CPOPJ1 CPOPJ DTEXX KLTYO KLTYI TYI KLTYI1 POPCJ TYICAN FILTYP PPNTYP TYPSIX TYPSI1 TWAIT OCTTYP OCTTY1
C00092 00013	 C1ZERO C1APT C1BPT C1PH C1ZEND C1FRST C1ERR C1PTP C1PPTP C1CIFI ZZZ C1MRTC C1CCHR C1MRTD C1WCHN RCLTAB XBUF LPDL LPDL PDL ERRCNT RECORD NXTTRK SYMPNT SYSLOC PATCH LODCNT LODNXT XFRCNT STARTA KASIM MUCKFL ZERFLG FHILOC UPPRST TIBFLN TIBUF FDEV FNAM FEXT FPPN DEFDEV DEFEXT DEFPPN
C00100 00014	AC CONVENTIONS IN THIS PROGRAM:
C00105 00015	MONITOR PARAMETERS WHICH MUST AGREE WITH COMMON/COMMOD.  HOMNAM HOMSNM HOMLUN HOMHOM HOMRXB HOMSIZ HOMFSN HOMCOD HOMSLF CODHOM RIBFIR RIBPPN RIBNAM RIBEXT RIBSIZ RIBSTS RIPDMP RIBXRA RIPNUB RIBCOD CODRIB RIBSLF BOOTSA BOOTWD LBNHOM LB2HOM LBOBAT LIMLVL MBTCOM MAXPGS .EPHSB
C00112 00016	MISCELANEOUS HARDWARE PARAMETERS  IT.DON IT.BSY APRRST CLRAPR PDLLEN LINBFL BLKSIZ PAGSIZ MAXUNI P2BLSH B2WLSH W2BLSH P2WLSH W2PLSH .VBOOT .VPAG0 .VMOVE .VZERO .MBOOT .MPAG0 .MMOVE .MZERO
C00118 00017	IFN FTKL10!FTKI10,<  CI.XDN CI.122 CI.1ER CI.1RA CI.2ER CI.2RA CO.XDN CO.XSX CO.XMI CO.1RB CO.1AE CO.2RB CO.2ME DO.XCR DO.XSR DI.XCE DI.XSM DI.XSB DO.XDS DO.XDT DO.XDC DO.1CR DO.2ST DO.XCL DO.XRP DO.XRD DO.XWT RH2TRA RH2JMP R2IOWL R2BCNT R2WCNT R1BCNT R1WCNT
C00125 00018	IFN FTKS10,<  SO.UPR SO.VFT SO.RBT SO.USR SO.UBI SI.UER SO.CS1 SI.RDY SI.S1E SO.WC SO.BA SO.DA SO.CS2 SO.DS SO.DSM SO.DSB SI.DT SI.DSK SO.DC SO.DCL SO.RIP SO.WRT SO.RED RSBCNT
C00131 00019	MACROS TO HELP IN INSERTING ENTRIES INTO THE PAGE MAP  BLK STALL
C00135 00020	BLK(HOM,BLKSIZ)		HOM BLOCK FOR CURRENT UNIT  SWTVLV SWTVLL FILSPE NXMTBE
C00141 00021		SUBTTL	BLOCK READ/WRITE SUBROUTINES  WRTRIB WRTBUF REDBUF
C00146 00022	ROUTINE TO FIND A UNIT AND READ IT'S HOM BLOCK. CALL WITH LUNPOS  FNDLUN FNDUNI FNDUN1 FNDUN2 FNDUN3
C00152 00023	ROUTINE TO READ A HOM BLOCK.  REDHOM REDHO1 REDHO2
C00157 00024	ROUTINE TO SETUP A TRANSFER TO/FROM DISK.  SELBLK SELBL1 SELBL2 SELBL3
C00163 00025	SELBL4:	MOVN	M,T1		GET -VE NUMBER OF BLOCKS IN REQUEST  SELBL4 SELBL5 SELBL6
C00169 00026		SUBTTL	SUPPORT SUBROUTINES  CLRBUF SETIOT ERRTAB SNTERR FNTERR UPDERR EOFERR IOFERR BDFERR MCCERR NSSERR ERRTBL ALLERR
C00174 00027	ROUTINE TO READ DATA INTO A VIRTUAL ADDRESS.  VRTRED VRTWRT MAPADR
C00180 00028	ROUTINE TO SAVE P1 AND P2 AND CALL THE CALLER AS A COROUTINE  SAVE2 SAVFR
C00185 00029		SUBTTL	DISK SUPPORT SUBROUTINES  REDREG DRVTYP DRVTY1
C00190 00030	TABLES DEFINING THE DRIVE TYPES OF THE DRIVES WE KNOW ABOUT AND  DRTTAB DRTTBL BPCTAB BPTTAB
C00195 00031		SUBTTL	BYTE POINTERS INTO DATA STRUCTURES  DESRBU DENRBU DESRBA DENRBA DEYRBU DEYRBA
C00199 00032		SUBTTL	TABLES DRIVING DEVICE DEPENDENT I/O  DVCTAB DVCTBL IOTTAB DODATO DODATI DOCONI DOCONO DOCNSO IOTTBL
C00204 00033	THE FOLLOWING TABLES GIVE THE DISPATCH ADDRESSES FOR THE CONTROLLER  OFS REDTAB WRTTAB
C00209 00034	IFN FTKL10!FTKI10,<  R12WRT R12RED R12XFR R10XFR R12XF1
C00215 00035	ROUTINE TO SETUP THE CHANNEL COMMAND LIST FOR THIS TRANSFER AND  R12SET R12SE1 R12SE2 R12SE3 R12SE4 R12SE5 R12SE6
C00222 00036	ROUTINE TO INITIALIZE THE RH10/RH20 FOR A TRANSFER.  R12INI R12CHK
C00227 00037	ROUTINE TO WAIT FOR THE RH10/RH20 TO FINISH A TRANSFER.  R12WAT R12CLR
C00232 00038	IFN FTKS10,<  R11WRT R11RED R11XFR R11XF1
C00238 00039	ROUTINE TO SETUP THE UBA MAPPING REGISTERS, AND THE DRIVE REGISTERS  R11SET R11SE1
C00244 00040	ROUTINE TO INITIALIZE THE RH11 FOR A TRANSFER.  R11INI R11CLR
C00246 00041	FF
C00272 ENDMK
C⊗;
;⊗ DEBSW DSKDSW DSKDBG KLBOOT RHDSK FT1DSK EXTNEW KACODE NPACKS EXTNEW DEBSW DSKDBG F A B C D E H J K L M N T TT P HILOC NUFDWD RBO CUADR APR PI KLPAG CCA TTY C1A C1B RH0 DTE0 DTFLG DTF11 DTCMD DONG11 SWEEPB PIOFF DSTART KLEPT

;ASSEMBLY SWITCHES, TITLE AND AC DEFINITIONS

;"BOOT" means the program that's loaded into 11 memory that runs in response to
;the DS command in KLDCP.
;
;"DSKDMP" means the program that's run by BOOT.  It generally has DDT and a
;file name scanner, etc.

DEBSW←←0		;IF BOOT, 0 FOR PAPER TAPE, 1 FOR DECTAPE WITH EDDT
			;IF DSKDMP, 0 FOR REAL DSKDMP, 1 FOR DSKDMP WITH EDDT
DSKDSW←←1		;0 FOR BOOT, 1 FOR DSKDMP
DSKDBG←←0		;1 FOR BEING ABLE TO LOAD DSKDMP WITH EDDT
KLBOOT←←1		;IF BOOT, 1 FOR KLDCP LOADABLE BOOT, 0 FOR PAPER TAPE
RHDSK←←1		;nonzero for RH20 disks, else C1 channel disks
FT1DSK←←1		;1 IF ALL C1 DISK PACKS ARE ON SAME CONTROLLER (IFE RHDSK)
EXTNEW←←0		;IF BOOT, 0 FINDS DSKDMP.DMP, 1 FINDS .NEW, 2 FINDS .OLD
KACODE←←0		;1 to include run time checks for KA-10 and KASIM microcode

NPACKS←←8

DEFINE SWLIST <FOR SWITCH IN (DEBSW,DSKDSW,DSKDBG,KLBOOT,RHDSK,FT1DSK,EXTNEW)>

DEFINE VALPNT (VAL) <
PRINTS /VAL/
>
PRINTS /SWITCHES ARE:
/

SWLIST <
PRINTS /SWITCH(/
VALPNT (\SWITCH)
PRINTS /) /
>

PRINTS /
TYPE NEW VALUES FOR THESE SYMBOLS, IF ANY, FOLLOWED BY CONTROL-META-LF
/
.INSERT TTY:

SWLIST <
IFDIF <SWITCH><EXTNEW><
IFN SWITCH,<↓SWITCH←←1>
IFE SWITCH,<↓SWITCH←←0>
>;IFDIF
>;SWLIST
IFL EXTNEW,<.FATAL EXTNEW has illegal value, must be 0, 1 or 2.>
IFG EXTNEW-2,<.FATAL EXTNEW has illegal value, must be 0, 1 or 2.>
↓EXTNEW←←EXTNEW

IFN DSKDSW,<KLBOOT←←0>
IFN KLBOOT,<
DEBSW←←0
DSKDBG←←0
>;KLBOOT

IFN DSKDSW,<
TITLE DSKDMP
>;DSKDSW

IFE DSKDSW,<
IFE EXTNEW,<	TITLE BOOT	>
IFE EXTNEW-2,<	TITLE OBOOT	>
IFE EXTNEW-1,<	TITLE NBOOT	>
>;IFE DSKDSW

F←0
A←1
B←2
C←3
D←4
repeat 0,< ;unused
E←5
H←7
J←10
K←11
L←12
M←13
>;repeat 0
ifn rhdsk,<
P1←5
P2←6
P3←7
P4←10
T1←11
T2←12
T3←13
>;ifn rhdsk
N←14
T←15
TT←16
P←17

HILOC←←135

NUFDWD←←20

IFN DSKDSW,<
;RIGHT HALF F BITS
RBO←←1			;DOING RUBOUT NOW
>;DSKDSW

↓CUADR←←6			;CONTROL UNIT ADDRESS

APR←←0
PI←←4
KLPAG←←10
CCA←←14
TTY←←120
IFE RHDSK,<
C1A←←140
C1B←←144
>;IFE RHDSK
IFN RHDSK,<
RH0←←540
>;IFN RHDSK
DTE0←←200

;KL10 PARAMETERS, offsets within EPT
DTFLG←←444		;DTE20 OPERATION COMPLETE FLAG
DTF11←←450		;      FROM 11 ARGUMENT
DTCMD←←451		;      TO 11 COMMAND

IFN KACODE,<
DEFINE SKPKA <CONSO TTY,1B28>	;SKIP IF THIS IS THE KA10
DEFINE SKPKL <CONSZ TTY,1B28>	;SKIP IF THIS IS THE KL10
>;IFN KACODE
IFE KACODE,<
;DEFINE SKPKA <CAI>		;SKIP IF THIS IS THE KA10 (never)
;DEFINE SKPKL <CAIA>		;SKIP IF THIS IS THE KL10 (always)
>;IFE KACODE

DONG11←←20000				;DTE CONO BIT.  REQUEST 11 INTERRUPT
SWEEPB←←200000				;KL10 APR CONI BIT - SWEEP BUSY
PIOFF←←400

IFN DEBSW,<
	LOC 74
	JRST DDT↑
IFN DSKDSW,<
	LOC 140
	274
	FF
	LOWEST
>;DSKDSW
	LOC 300
	JRST DDT
IFE DSKDSW,<
	JRST BOOT
	LOC 100000
>;IFE DSKDSW
IFN DSKDSW,<
	JRST DSKDMP
	LOC 300000
>;IFN DSKDSW
>;IFN DEBSW

IFE DEBSW,<
IFN DSKDSW,<
DSTART←←760000		;address where DSKDMP code will start
KLEPT←←<DSTART-1000>&777000 ;the KL EPT will be in the previous page
	LOC 140
	DSTART		;LOCATION FOR LOADING STARTING AT 274
	FF		;FIRST FREE
	LOWEST		;LOWEST LOCATION USED
	LOC 274
	PHASE DSTART
>;IFN DSKDSW
>;IFE DEBSW
;PTPC PTR PNCHGO GO1 GO2 PUNCHC PUNCH RIMLDR RIMLDL RIMPDL OBUF BOOTLO BOOTBG XBUF XBUF BOOTBG XBUF

;WRITE OUT RIM FORMAT BOOT, PNCHGO

IFE DSKDSW,<
IFE KLBOOT,<
IFE DEBSW,<

PTPC←←1
PTR←←104

LOC 200

PNCHGO:	RESET
	MOVE P,[-20,,RIMPDL]
	INIT PTPC,13
	SIXBIT /PTP/
	OBUF,,
	JRST 4,.
	MOVSI C,-RIMLDL
GO1:	MOVE A,RIMLDR(C)
	PUSHJ P,PUNCH
	AOBJN C,GO1
	MOVEI D,0		;INITIALIZE CHECKSUM
	MOVE A,[BOOTBG,,BOOTBG]
	PUSHJ P,PUNCHC
	MOVSI C,BOOTBG
GO2:	MOVE A,BOOTLO(C)
	PUSHJ P,PUNCHC		;PUNCH AND CHECKSUM
	AOBJN C,GO2
	MOVE A,D
	PUSHJ P,PUNCH		;PUNCH OUT CHECKSUM
	MOVE A,[JRST BOOT]
	PUSHJ P,PUNCH
	MOVEI A,0
	PUSHJ P,PUNCH
	EXIT

PUNCHC:	ROT D,1
	ADD D,A
PUNCH:	SOSG OBUF+2
	OUT PTPC,
	CAIA
	JRST 4,.
	IDPB A,OBUF+1
	POPJ P,

RIMLDR:	-17,,0			;IOWD TO RIM LOADER
	CONO PTR,60
	HRRI 11,4
	CONSO PTR,10
	JRST 3
	ROT 0,-2(11)
	DATAI PTR,@10(11)
	XCT 10(11)
	XCT 13(11)
	SOJA 11,0
	CAME 0,17
	ADD 0,(17)
	SKIPL 17,0
	JRST 4,1
	AOBJN 17,3
	JRST 2
RIMLDL←←.-RIMLDR

RIMPDL:	BLOCK 20
OBUF:	BLOCK 3

LIT
VAR

LOC 1000

BOOTLO:
BOOTBG←←777000
PHASE BOOTBG
XBUF←←BOOTBG-4440
>;IFE DEBSW
>;IFE KLBOOT
>;IFE DSKDSW

IFN DEBSW,<
IFE DSKDSW,<
XBUF:	BLOCK 4440
>;IFE DSKDSW
>;IFN DEBSW

IFN KLBOOT,<
IFE DEBSW,<
BOOTBG←←777000			;CHANGE TO 777000 WHEN SOME MEMORY IS UP THERE
	LOC 140
	BOOTBG
	FF
	LOWEST
	LOC 274
	PHASE BOOTBG
XBUF←←BOOTBG-4440
>;IFE DEBSW
>;KLBOOT
;C1SBI C1RSI C1SRUN C1CONT C1SCH C1RST C1CCIF C1INTE C1INTD C1SCF1 C1CCF1 C1MPCN C1LCD C1LPT C1SYSR C1SCAN C1SDIA CIF CF1 CF2 C1UCHK

;C1 CHANNEL DEFINITIONS

IFE RHDSK,<

;CONO C1A BITS

C1SBI←←400000		;SELECT BUS INTERFACE
  C1RSI←←40000		;RESET INTERFACE
  C1SRUN←←10000		;SET CLOCK RUN
  C1CONT←←2000		;CONTINUE CLOCK
C1SCH←←200000		;SELECT CHANNEL
  C1RST←←40000		;RESET CHANNEL
  C1CCIF←←20000		;CLEAR CHANNEL INTERRUPT FLAG
  C1INTE←←10000		;INTERRUPT ENABLE
  C1INTD←←4000		;INTERRUPT DISABLE
  C1SCF1←←2000		;SET CF1
  C1CCF1←←1000		;CLEAR CF1
  C1MPCN←←400		;CONTINUE MICROPROCESSOR
  C1LCD←←20		;LOAD CODE FROM BITS 32-35
;BITS 32-35 ARE A CODE, BIT 32 IS OFF FOR "SOFTWARE" CODES:
  C1LPT←←11		;LOAD PROGRAM TABLE STARTING ADDRESS
  C1SYSR←←2		;SYSTEM RESET
  C1SCAN←←7		;SCAN PROGRAM TABLE FOR PROGRAMS TO START

C1SDIA←←100000		;SELECT DIAGNOSTIC FUNCTIONS

;CONI C1A BITS

CIF←←4			;CHANNEL INTERRUPT FLAG
CF1←←2			;CHANNEL FLAG 1 (INTERRUPT THE Z80, SET FROM ICH IN CONO)
CF2←←1			;CHANNEL FLAG 2 (Z80 READY FOR PROGRAM TABLE ADDRESS)

C1UCHK←←2		;UNIT CHECK IN IBM STATUS BYTE

>;IFE RHDSK
;C1CMD C1MRT C1JMP C1TIO C1IWC C1BAK C1NATM C1BYTM C1CBYT C1SLE C1CEC C1NOC C1RPT C1CCW C1ISW C1PTPE C1PTNX C1IQF C1PPTR C1PCW C1BW C1STA C1HLT C1LE C1SE C1PE C1NXM C1BPE C1SSE C1PCMA C1STB C1STC C1INST

;C1 CHANNEL DATA AREA PARAMETERS

IFE RHDSK,<

;CHANNEL PROGRAM DEFINITIONS
;LEFT HALF BITS
C1CMD←←100000			;BITS 0-3 = 10 MEANS (NON-MRT) COMMAND WORD
C1MRT←←040000			;BITS 0-3 = 04 MEANS MRT COMMAND WORD
C1JMP←←200000			;BITS 0-3 = 20 MEANS JUMP COMMAND WORD
C1TIO←←020000			;TEST I/O
C1IWC←←010000			;IGNORE WORD COUNT
C1BAK←←004000			;BACKWARDS
C1NATM←←000000			;NATURAL MODE (MODE IN BITS 7-8)
C1BYTM←←001000			;BYTE MODE
C1CBYT←←000400			;COUNT BYTES
				;BITS 10-17 ARE THE IBM COMMAND BYTE
;RIGHT HALF BITS
C1SLE←←20			;STOP ON LENGTH ERROR
C1CEC←←10			;CHANNEL END CONTINUE
C1NOC←←2			;NO CHAINING
C1RPT←←1			;REPEAT UNTIL STATUS MODIFIER IS ON IN ENDING STATUS




;PROGRAM TABLE
C1CCW←←0			;RELATIVE ADDRESS OF CHANNEL CONTROL WORD
C1ISW←←1			;INTERRUPT SOURCE WORD
   C1PTPE←←100000		;PARITY ERROR IN PROGRAM TABLE
   C1PTNX←←40000		;NXM IN PROGRAM TABLE
   C1IQF←←20000			;INTERRUPT QUEUE FULL
C1PPTR←←2			;FIRST PROGRAM POINTER

;PROGRAM HEADER AND PROGRAM
C1PCW←←0			;RELATIVE ADDRESS OF PROGRAM CONTROL WORD
   C1BW←←100			   ;BUSY WAIT BIT IN PCW
C1STA←←1			;STATUS A
  ;RIGHT HALF BITS
   C1HLT←←400000		;PROGRAM EXECUTED A HALT
   C1LE←←200000			;LENGTH ERROR
   C1SE←←100000			;SELECT ERROR
   C1PE←←040000			;PARITY ERROR
   C1NXM←←020000		;NXM
   C1BPE←←010000		;IBM BUS PARITY ERROR
   C1SSE←←002000		;SIGNAL SEQUENCE ERROR
  ;LEFT HALF BITS
   C1PCMA←←100000		;1→ERROR POINTER TO BY PC, 0→POINTED TO BY MA
C1STB←←2			;STATUS B
C1STC←←3			;STATUS C
C1INST←←4			;FIRST INSTRUCTION OF CHANNEL PROGRAM
>;IFE RHDSK
;MFDLOC TRKCYL CYLPK TRKPK NXTQQQ A NXTQQQ NXTQQQ

;FILE SYSTEM PARAMETERS

IFE RHDSK,<
MFDLOC←←1		;TRACK CONTAINING MFD

TRKCYL←←=19		;19 HEADS PER CYLINDER
CYLPK←←=815		;815 CYLINDERS PER PACK
TRKPK←←TRKCYL*CYLPK	;19*815=15485 TRACKS PER PACK
>;IFE RHDSK

;RETRIEVAL INFORMATION

NXTQQQ←←0

DEFINE ZWD (A) <
A←←NXTQQQ
NXTQQQ←←NXTQQQ+1
>

	ZWD DDNAM	;FILE NAME
	ZWD DDEXT	;FILE EXTENSION,,DATE WRITTEN,CREATION DATE
	ZWD DDPRO	;PROTECTION,MODE,TIME,DATE WRITTEN
	ZWD DDPPN	;PPN
	ZWD DDLOC	;FIRST DISK ADDRESS OF THIS FILE
	ZWD DDLNG	;LENGTH OF FILE IN WORDS
	ZWD DREFTM
	ZWD DDMPTM
	ZWD DGRP1R	;FIRST USER RCRD NO. THIS GRP
	ZWD DNXTGP	;BLOCK NUMBER OF NEXT GROUP
	ZWD DSATID
	ZWD DQINFO	;START OF SPECIAL STORAGE FOR LOGIN ETC.
NXTQQQ←←NXTQQQ+3
	ZWD DOFFST	;RECORD OFFSET
	ZWD DPTR	;RETRIEVAL DATA, 2 BLK NO.'S/WORD
;DSKDMP.DMP FORMAT

COMMENT ⊗

DSKDMP.DMP[SS,SYS] IS AN ORDINARY DUMP FILE EXCEPT THAT IT HAS BEEN
ASSEMBLED WITH A PHASE STATEMENT AND EXPECTS TO BE LOADED HIGH IN
THE FIRST 256K OF CORE.  LOCATION 140 OF THE CORE IMAGE THAT WOULD
HAVE BEEN OBTAINED BY LOADING DSKDMP CONTAINS THE STARTING ADDRESS
FOR LOADING.  LOCATION 274 IS THE FIRST WORD THAT SHOULD BE LOADED
THERE.  LOCATION 141 CONTAINS THE RELOCATED FIRST FREE ADDRESS, 142
CONTAINS THE RELOCATED LOWEST ADDRESS.  THESE TWO LOCATIONS ARE USED
ONLY BY THE CNVRT PROGRAM TO MAKE DSKDMP.D10

⊗
;LOWEST BOOT BOOT1 BOOTL1 BOOTL2 BOOTL3 NODSKD NOSYS ;⊗ LOWEST BOOT BOOT1 BOOTL1 BOOTL2 BOOTL3 NOMFD NODSKD NOSYS NOMFD0

;BOOT BEGINS HERE

IFE DSKDSW,<
LOWEST←←.
BOOT:	CONO APR,200000			;RESET
	SETZM KASIM
IFN KACODE,<
	BLKI APR,A			;GET UCODE OPTIONS INTO BITS 0-8 OF A
	TLNE A,100000			;SKIP UNLESS KA SIMULATION UCODE LOADED
	SETOM KASIM
>;IFN KACODE
	MOVE P,[-LPDL,,PDL-1]
	PUSHJ P,BLAST			;RESET THE CHANNEL
IFN DSKDBG,<
	SKIPE N,SYSLOC
	JRST BOOT1
>;DSKDBG
IFN RHDSK,<
	PUSHJ P,FNDMFD		;get location of the MFD
	 JRST NOMFD		;failed
	MOVE N,MFDADR		;pick up ptr to MFD
>;IFN RHDSK
IFE RHDSK,<
	MOVEI N,MFDLOC
>;IFE RHDSK
	MOVE A,[SIXBIT / SSSYS/]
	PUSHJ P,SRCH			;LOOK FOR _SSSYS.UFD IN MFD
	 JRST NOSYS
	MOVE N,3(TT)			;GET ADDRESS
IFN DSKDBG,<
	MOVEM N,SYSLOC
>;DSKDBG
BOOT1:	MOVE A,[SIXBIT /DSKDMP/]
IFE EXTNEW,<	MOVSI B,'DMP'	>
IFE EXTNEW-1,<	MOVSI B,'NEW'	>
IFE EXTNEW-2,<	MOVSI B,'OLD'	>
	PUSHJ P,SRCH1			;LOOK FOR DSKDMP.DMP[SS,SYS]
	JRST NODSKD
	MOVE N,3(TT)			;GET DISK ADDRESS OF DSKDMP.DMP[SS,SYS]
	MOVE T,[-240,,XBUF]
	SETZM RECORD
	PUSHJ P,READ0			;READ RETRIEVAL AND ONE RECORD
	MOVE A,XBUF+40+140-74		;GET LOC 140 OF THE DUMP FILE
	MOVE B,XBUF+DDLNG		;GET LENGTH OF DUMP FILE
IFN DSKDBG,<
	MOVE C,XBUF+40+JOBSYM↑-74	;GET POINTER TO SYMBOL TABLE
	ADDI C,-274(A)			;RELOCATE IT
	MOVEM C,SYMPNT
>;DSKDBG
	MOVE C,XBUF+40+JOBSA↑-74	;GET STARTING ADDRESS
	HRRZM C,STARTA
	SUBI B,200
	MOVEM B,LODCNT			;LENGTH OF REMAINDER OF DUMP FILE
	MOVEM A,LODNXT			;STORE ADDRESS TO LOAD INTO
	MOVEI B,2
	MOVEM B,RECORD			;START AT RECORD 2
	MOVE C,[POINT 18,XBUF+DPTR]
	MOVEM C,NXTTRK
	MOVE T,LODCNT
	CAILE T,4400-200
	MOVEI T,4400-200
	JRST BOOTL2

BOOTL1:	MOVE T,LODCNT
	MOVEI N,1
	MOVEM N,RECORD
BOOTL2:	ILDB N,NXTTRK
	CAILE T,4400
	MOVEI T,4400
	MOVEM T,XFRCNT			;SAVE NUMBER OF WORDS THIS TRANSFER
	MOVN T,T			;-NUMBER OF WORDS TO TRANSFER
	HRLZ T,T
	HRR T,LODNXT			;RH GETS NEXT LOC TO LOAD INTO
	PUSHJ P,READ0			;READ REST OF THIS TRACK
	MOVE A,XFRCNT
	ADDM A,LODNXT
	MOVN A,A
	ADDB A,LODCNT
IFN DSKDBG,<
	JUMPLE A,BOOTL3			;ALL DONE
>;DSKDBG
IFE DSKDBG,<
	JUMPLE A,@STARTA		;DONE, TRANSFER TO DSKDMP
>;IFE DSKDBG
	MOVE A,NXTTRK
	CAME A,[POINT 18,XBUF+DPTR+17,35]	;JUST DID LAST TRACK IN GROUP?
	JRST BOOTL1			;NO, DO NEXT TRACK
	MOVE N,XBUF+DNXTGP		;FIRST TRACK OF NEXT GROUP
	PUSHJ P,RDRET			;READ RETRIEVAL
	MOVE A,[POINT 18,XBUF+DPTR]
	MOVEM A,NXTTRK
	JRST BOOTL1

IFN DSKDBG,<
BOOTL3:	SETOM 37
	MOVE A,SYMPNT
	MOVEM A,36
	JRST @STARTA			;JUMP TO STARTING ADDRESS
>;DSKDBG

IFH RHDSK,<
NOMFD:	PUSHJ P,NOMFD0		;say can't find MFD
	JRST 4,BOOT
>;IFN RHDSK

NODSKD:
IFE EXTNEW,<	SKIPA B,[[ASCIZ /CAN'T FIND DSKDMP.DMP[SS,SYS]/]] >
IFE EXTNEW-1,<	SKIPA B,[[ASCIZ /CAN'T FIND DSKDMP.NEW[SS,SYS]/]] >
IFE EXTNEW-2,<	SKIPA B,[[ASCIZ /CAN'T FIND DSKDMP.OLD[SS,SYS]/]] >
NOSYS:	MOVEI B,[ASCIZ /CAN'T FIND SSSYS.UFD[1,1]/]
	PUSHJ P,TYPE
	JRST 4,.

>;IFE DSKDSW

IFN RHDSK,<
NOMFD0:	MOVEI B,[ASCIZ /Can't find MFD.
/]
	JRST TYPE
>;IFN RHDSK
;LOWEST DSKDMP DSKDM0 DSKDM1 DSKDM2 DSKDL DSKDL2 DSKDL1 DSKDRO DSKDAL DSKAL1 QQQ DSKDGO CMDS NCMDS CMDDSP SSTRTA SSTRT1 SSTRT2 START LOADGO NOMUCK MERGE LOAD LOADN LOADIT LDIT0 LDIT0A LDIT1 LDIT3 LDIT4 LDIT2 LDLP LDLP1 LDLP3 FILES DUMP KILL NSA FNF

;DSKDMP BEGINS HERE

IFN DSKDSW,<
LOWEST←←.
DSKDMP:	MOVE P,[-LPDL,,PDL-1]
	CONO APR,200000
	CONO PI,10000
IFN KACODE,<
	SKPKL
	JRST DSKDM1
>;IFN KACODE
	CONSZ APR,SWEEPB	;WAIT FOR SWEEP BUSY TO FALL
	JRST .-1
	CONSO KLPAG,600000	;IS THE CACHE ON ALREADY?
	JRST DSKDM0		;NO.
	BLKO CCA,		;VALIDATE CORE
	CONSZ APR,SWEEPB
	JRST .-1
DSKDM0:	SETZM KLEPT		;clear the channel logout areas
	MOVE A,[KLEPT,,KLEPT+1]
	BLT A,KLEPT+MAXCHN*WDPCHN-1 ;clear all channels' logout areas
	CONO KLPAG,KLEPT⊗-9	;TURN OFF CACHE.  set EPT address.  TURN OFF MAP
	DATAI CCA,0		;SWEEP CACHE.  INVALIDATE ALL.
	CONSZ APR,SWEEPB	;WAIT FOR SWEEP BUSY TO FALL
	JRST .-1

IFN KACODE,<
	BLKI APR,A		;GET UCODE OPTIONS INTO BITS 0-8 OF A
	TLNN A,100000		;SKIP IF KA SIMULATION UCODE LOADED
	JRST DSKDM1
	SETOM KASIM
	CONO KLPAG,KLEPT⊗-9	;MAKE SURE EPT IS AT right place
	MOVEI C,411
	PUSHJ P,DTEXX		;TELL KLDCP TO ENTER KASIM MODE
IFN RHDSK,<
PRINTX This can't possibly work, since EPT isn't where RH routines expect it
>;IFN RHDSK
	CONO KLPAG,1000		;MOVE EPT TO PAGE 1000
	PUSHJ P,BLAST
	JRST DSKDM2

>;IFN KACODE
DSKDM1:	PUSHJ P,BLAST
	SETZM KASIM
IFN KACODE,<
	SKPKL
	CONO TTY,3600		;CLEAR ALL BUSY AND DONE FLAGS
	SKIPN KASIM
>;IFN KACODE
	SKIPA B,[SIXBIT /  SSYS/]
DSKDM2:	MOVE B,[SIXBIT /  DSYS/];DIAGNOSTICS LIVE HERE
	MOVEM B,DEFPPN
	MOVEI F,0
	MOVEI B,[ASCIZ /DSKDMP/]
	PUSHJ P,TYPE
IFN KACODE,<
	SKIPN KASIM
	JRST DSKDL
	MOVEI B,[ASCIZ /
KA SIMULATION MICROCODE LOADED
SWITCHES = /]
	PUSHJ P,TYPE
	DATAI APR,B
	PUSHJ P,OCTTYP
>;IFN KACODE
DSKDL:	MOVEI B,[ASCIZ /
*/]
	PUSHJ P,TYPE
	TRZ F,RBO
	MOVEI B,0
DSKDL2:	MOVE A,[010700,,TIBUF-1]
	SETZM TIBUF
	MOVE C,[TIBUF,,TIBUF+1]
	BLT C,TIBUF+TIBFLN-1
DSKDL1:	PUSHJ P,TYI			;GET CHARACTER IN C
	CAIN C,177
	JRST DSKDRO			;RUBOUT
	TRZE F,RBO
	JRST [	PUSH P,C
		MOVEI C,"\"
		PUSHJ P,TYO
		POP P,C
		PUSHJ P,TYO
		CAIE C,15
		JRST .+1
		MOVEI C,12
		PUSHJ P,TYO
		MOVEI C,15
		JRST .+1  ]
	CAIN C,15
	JRST DSKDGO
	CAIN C,33
	JRST DSKDAL			;ALT MODE
	CAIN C,"U"-100
	JRST DSKDL
	IDPB C,A
	JRST DSKDL1

DSKDRO:	CAMN A,[010700,,TIBUF-1]
	JRST DSKDL
	MOVEI C,"\"
	TRON F,RBO			;SET RUBOUT FLAG, SKIP IF ALREADY ON
	PUSHJ P,TYO
	LDB C,A
	PUSHJ P,TYO
	MOVEI C,0
	DPB C,A
	ADD A,[070000,,]
	JUMPGE A,DSKDL1
	SUB A,[430000,,1]
	JRST DSKDL1

DSKDAL:	LDB A,[POINT 7,TIBUF,6]		;GET FIRST CHARACTER
	CAIL A,"0"
	CAILE A,"9"
	CAIA
	JRST SSTRTA			;SET STARTING ADDRESS
	MOVE A,TIBUF
	MOVSI B,-NCMDS
DSKAL1:	CAME A,CMDS(B)
	AOBJN B,DSKAL1
	JUMPL B,DSKDL2			;JUMP IF FOUND ONE (B REMEMBERS THE COMMAND)
	PUSHJ P,QQQ
	JRST DSKDL

QQQ:	MOVEI B,[ASCIZ /  ???/]
	JRST TYPE

DSKDGO:	JUMPE B,LOADGO			;JUST FILE NAME
	JRST @CMDDSP(B)			;DISPATCH ON COMMAND

CMDS:	ASCII /L/			;LOAD
	ASCII /F/			;LIST FILES
	ASCII /D/			;DUMP
	ASCII /K/			;KILL A FILE
	ASCII /G/			;START AT STARTING ADDRESS
	ASCII /M/			;MERGE (LOAD WITHOUT CLEAR)
	ASCII /N/			;LIKE L BUT DOESN'T HACK LOW CORE CELLS
NCMDS←←.-CMDS

CMDDSP:	LOAD
	FILES
	DUMP
	KILL
	START
	MERGE
	NOMUCK

SSTRTA:	MOVE A,[POINT 7,TIBUF]
	MOVEI B,0
SSTRT1:	ILDB C,A
	CAIL C,"0"
	CAILE C,"9"
	JRST SSTRT2
	LSH B,3
	ADDI B,-"0"(C)
	JRST SSTRT1

SSTRT2:	MOVEM B,STARTA
	JRST DSKDL

START:	PUSHJ P,TWAIT			;WAIT FOR TTY TO FINISH
	SKIPE STARTA
	JRST @STARTA
	MOVEI B,[ASCIZ /NO STARTING ADDRESS/]
	PUSHJ P,TYPE
	JRST DSKDL

LOADGO:	SETOM ZERFLG
	SETOM MUCKFL
	PUSHJ P,LOADIT
	JRST DSKDL			;COULDN'T DO IT
	MOVEI B,[ASCIZ / LOADED/]
	PUSHJ P,TYPE
	PUSHJ P,TWAIT
	SKIPE STARTA
	JRST @STARTA			;START IT UP
	MOVEI B,[ASCIZ / BUT NO STARTING ADDRESS/]
	PUSHJ P,TYPE
	JRST DSKDL

NOMUCK:	SETOM ZERFLG
	SETZM MUCKFL
	JRST LOADN

MERGE:	SETZM ZERFLG
	SETOM MUCKFL
	JRST LOADN

LOAD:	SETOM ZERFLG
	SETOM MUCKFL
LOADN:	PUSHJ P,LOADIT
	JRST DSKDL			;COULDN'T DO IT
	MOVEI B,[ASCIZ / LOADED/]
	PUSHJ P,TYPE
	JRST DSKDL

;SKIP RETURNS IF SUCCESSFUL
LOADIT:	PUSHJ P,FILSET			;SET UP FILE NAME
	SKIPN FNAM
	JRST QQQ
IFN RHDSK,<
	PUSHJ P,FNDMFD		;get location of the MFD
	 JRST NOMFD0		;can't find MFD
	MOVE N,MFDADR		;pick up ptr to MFD
>;IFN RHDSK
IFE RHDSK,<
	MOVEI N,MFDLOC
>;IFE RHDSK
	MOVE A,FPPN
	MOVEM A,DEFPPN
	PUSHJ P,SRCH
	JRST NSA			;UFD NOT FOUND IN MFD
	MOVE N,3(TT)			;DISK ADDRESS OF UFD
	MOVE A,FNAM
	HLLZ B,FEXT
	PUSHJ P,SRCH1
	JRST FNF			;FILE NOT FOUND IN UFD
	MOVE N,3(TT)			;DISK ADDRESS OF FILE
	SKIPN ZERFLG
	JRST LDIT0
	SETZM 40
	MOVE A,[40,,41]
	BLT A,DSKDMP-1			;CLEAR CORE UP TO DSKDMP
LDIT0:	MOVE T,[-240,,XBUF]
	SETZM RECORD
	PUSHJ P,READ0			;READ RETRIEVAL AND ONE RECORD
	SETZB C,FHILOC
	SETZM STARTA
	SKIPN MUCKFL			;SKIP IF MUCKING WITH LOW CORE CELLS
	JRST LDIT0A
	MOVE C,XBUF+40+JOBSYM↑-74	;GET POINTER TO SYMBOL TABLE
	MOVEM C,SYMPNT			;SAVE FOR LATER
	MOVE C,XBUF+40+JOBSA↑-74	;GET STARTING ADDRESS
	HRRZM C,STARTA
	MOVE C,XBUF+40+HILOC↑-74	;ADDRESS OF BEGINNING OF UPPER
	MOVEM C,FHILOC
LDIT0A:	MOVE B,XBUF+DDLNG		;GET LENGTH OF DUMP FILE
	JUMPE C,LDIT1			;NO UPPER
	MOVEI B,-74(C)			;FILE SIZE OF LOWER
	SUBI C,1
	IORI C,1777			;LAST ADDRESS OF LOWER
	CAIGE C,377777
	MOVEI C,377777
	ADDI C,1
	MOVEM C,UPPRST			;UPPER STARTS HERE
LDIT1:	MOVEM B,LODCNT
	MOVEI A,74
	MOVEM A,LODNXT			;STORE ADDRESS TO LOAD INTO
	PUSHJ P,LDLP			;LOAD THE LOWER
	SKIPN C,FHILOC			;SKIP IF THERE IS AN UPPER
	JRST LDIT2			;NO UPPER
	MOVE B,XBUF+DDLNG
	SUBI B,-74(C)			;COMPUTE SIZE OF UPPER
	MOVEM B,LODCNT
	MOVE B,UPPRST
	MOVEM B,LODNXT			;STARTING CORE ADDRESS OF UPPER
	MOVE A,RECORD			;NEXT RECORD TO READ IS FIRST REC OF UPPER
	CAIN A,=19
	JRST LDIT3			;UPPER BEGINS ON A TRACK BOUNDARY
	MOVN T,A
	ADDI T,=19			;NUMBER OF RECORDS LEFT IN TRACK
	IMULI T,200			;NUMBER OF WORDS LEFT IN TRACK
	CAMLE T,LODCNT
	MOVE T,LODCNT
	LDB N,NXTTRK
	PUSHJ P,LDLP3
	JRST LDIT2

LDIT3:	MOVE A,NXTTRK
	CAME A,[POINT 18,XBUF+DPTR+17,35]
	JRST LDIT4
	MOVE N,XBUF+DNXTGP
	PUSHJ P,RDRET			;READ RETRIEVAL OF NEXT GROUP
	MOVE A,[POINT 18,XBUF+DPTR]
	MOVEM A,NXTTRK
LDIT4:	PUSHJ P,LDLP1			;LOAD THE UPPER
LDIT2:	MOVEI A,-1
	MOVEM A,37
	MOVE A,SYMPNT
IFN KACODE,<
	SKIPE KASIM
	MOVEI A,116			;PDP-6 DDT EXPECTS 36 TO POINT TO SYM PTR
>;IFN KACODE
	MOVEM A,36
	JRST CPOPJ1

;SET LODNXT TO FIRST LOCATION TO LOAD INTO, LODCNT TO NUMBER OF WORDS TO TRANSFER
;STARTS READING AT THE BEGINNING OF THE GROUP WHOSE RETRIEVAL IS IN XBUF
LDLP:	MOVE C,[POINT 18,XBUF+DPTR]
	MOVEM C,NXTTRK
LDLP1:	MOVE T,LODCNT
	MOVEI N,1
	MOVEM N,RECORD
	ILDB N,NXTTRK
LDLP3:	CAILE T,4400
	MOVEI T,4400
	MOVEM T,XFRCNT			;SAVE NUMBER OF WORDS THIS TRANSFER
	MOVN T,T			;-NUMBER OF WORDS TO TRANSFER
	HRLZ T,T
	HRR T,LODNXT			;RH GETS NEXT LOC TO LOAD INTO
	PUSHJ P,READ0			;READ THE TRACK
	MOVE A,XFRCNT
	ADDM A,LODNXT
	MOVN A,A
	ADDB A,LODCNT
	JUMPLE A,CPOPJ			;DONE
	MOVE A,NXTTRK
	CAME A,[POINT 18,XBUF+DPTR+17,35]	;JUST DID LAST TRACK IN GROUP?
	JRST LDLP1			;NO, DO NEXT TRACK
	MOVE N,XBUF+DNXTGP		;FIRST TRACK OF NEXT GROUP
	PUSHJ P,RDRET			;READ RETRIEVAL
	JRST LDLP

FILES:	MOVEI B,[ASCIZ /FILES COMMAND NOT IMPLEMENTED YET/]
	PUSHJ P,TYPE
	JRST DSKDL

DUMP:	MOVEI B,[ASCIZ /DUMP COMMAND NOT IMPLEMENTED YET/]
	PUSHJ P,TYPE
	JRST DSKDL

KILL:	MOVEI B,[ASCIZ /KILL COMMAND NOT IMPLEMENTED YET/]
	PUSHJ P,TYPE
	JRST DSKDL

NSA:	MOVEI B,[ASCIZ /NO SUCH AREA - /]
	PUSHJ P,TYPE
	JRST PPNTYP

FNF:	MOVEI B,[ASCIZ /NO SUCH FILE - /]
	PUSHJ P,TYPE
	JRST FILTYP
;⊗ FILSET FILSE0 FILSE1 FILSIX FILSI1 RADJ RADJ1

;SCAN TIBUF AND SET UP FILE NAME, EXTENSION AND PPN
FILSET:
IFN RHDSK,<
	MOVE B,DEFDEV		;set up default structure name (device)
	MOVEM B,FDEV
>;IFN RHDSK
	MOVE B,DEFPPN
	MOVEM B,FPPN
	MOVE B,DEFEXT
	MOVEM B,FEXT
	SETZM FNAM
	SETZM FEXT+1
	MOVE A,[010700,,TIBUF-1]
	PUSHJ P,FILSIX
IFN RHDSK,<
	CAIE D,":"		;device given?
	JRST FILSE0		;no, must be filename
	MOVEM B,FDEV		;yes, store device name
	PUSHJ P,FILSIX		;now read filename
FILSE0:
>;IFN RHDSK
	MOVEM B,FNAM
	CAIE D,"."
	JRST FILSE1
	PUSHJ P,FILSIX
	HLLZM B,FEXT
FILSE1:	CAIE D,"["
	POPJ P,
	PUSHJ P,FILSIX
	PUSHJ P,RADJ
	HLLM B,FPPN
	CAIE D,","
	POPJ P,
	PUSHJ P,FILSIX
	PUSHJ P,RADJ
	HLRM B,FPPN
	POPJ P,

FILSIX:	MOVEI B,0
	MOVE C,[440600,,B]
FILSI1:	ILDB D,A		;GET NEXT CHARACTER FROM BUFFER
	CAIE D,"."
	CAIN D,"["
	POPJ P,
	CAIE D,","
	CAIN D,"]"
	POPJ P,
	JUMPE D,CPOPJ
	SUBI D,40
	TLNE C,770000
	IDPB D,C
	JRST FILSI1

RADJ:	JUMPE B,CPOPJ
RADJ1:	TLNE B,77
	POPJ P,
	LSH B,-6
	JRST RADJ1
>;DSKDSW
;⊗ FNDMFD SRCH SRCH1 SRCH2 SRCH3 SRCHLP SRCH5 SRCH4 RDRET READ READ0 READC1 C1WAIT C1WAIA C1WAIB C1WERR C1DIE C1MPIL C1MPI1 C1SET BLAST RSTC1

IFN RHDSK,<
;Routine to set up ptr to MFD in MFDADR and skip if successful.
FNDMFD:	SKIPE N,MFDADR		;do we already know where MFD is?
	JRST CPOPJ1		;yes, just return it
	MOVE N,[STRNAM]		;get name of structure
	MOVEM N,DEV		;indicate which structure to look for
	PUSHJ P,FDSK		;scan all the disks for structure of interest
	 POPJ P,		;failed, msg already typed
	MOVE N,DIORG		;get ptr to MFD
	MOVEM N,MFDADR		;return ptr where expected
	JRST CPOPJ1

>;IFN RHDSK

;SRCH IS GIVEN A FILENAME IN A AND A TRACK IN N.
;SRCH1 IS GIVEN A FILENAME IN A, AN EXTENSION IN B AND A TRACK IN N
SRCH:	MOVSI B,'UFD'
SRCH1:	PUSHJ P,READ		;READ TRACK N INTO XBUF
	SKIPN T,DDLNG+XBUF	;GET FILE LENGTH
	POPJ P,
	MOVE TT,[POINT 18,DPTR+XBUF,17]
	MOVEM TT,NXTTRK
SRCH2:	MOVE TT,[-4400,,XBUF+40]
SRCH3:	HLLZ C,1(TT)
	CAMN A,(TT)
	CAME B,C
	JRST SRCHLP
	JRST CPOPJ1		;RETURN WITH POINTER IN TT

SRCHLP:	SUBI T,NUFDWD
	JUMPLE T,CPOPJ		;NOT FOUND
	ADD TT,[NUFDWD-1,,NUFDWD-1]
	AOBJN TT,SRCH3
	MOVE TT,NXTTRK
	CAMN TT,[POINT 18,DPTR+XBUF+17,35]	;LAST TRACK IN GROUP?
	JRST SRCH4				;YES
	ILDB N,NXTTRK
SRCH5:	PUSH P,T		;SAVE COUNT OF WORDS LEFT TO SEARCH
	PUSHJ P,READ		;READ IN THE NEXT TRACK
	POP P,T
	JRST SRCH2

SRCH4:	MOVE N,DNXTGP+XBUF	;BLOCK NUMBER OF FIRST TRACK NEXT GROUP
	MOVE TT,[POINT 18,DPTR+XBUF,17]
	MOVEM TT,NXTTRK
	JRST SRCH5

;RDRET READS RETRIEVAL OF TRACK WHOSE ADDRESS IS IN N
;READ READS ENTIRE TRACK WHOSE ADDRESS IS IN N
RDRET:	SKIPA T,[-40,,XBUF]
READ:	MOVE T,[-4440,,XBUF]		;ADDRESS OF BUFFER
	SETZM RECORD			;START READING AT RECORD ZERO
READ0:
IFE RHDSK,<
READC1:	PUSHJ P,C1MPIL			;HERE WITH WCMA IN T, COMPILE INTO MRT INST
	PUSH P,T			;SAVE RECORD NUMBER RETURNED BY C1MPIL
	SETZM C1ERR			;CLEAR ERROR COUNT
	PUSH P,N+1		;save AC N+1
	IDIVI N,TRKPK			;N←PACK, N+1←TRACK ON PACK
	EXCH N+1,(P)		;restore N+1, save track on pack
	POP P,T			;T←track on pack
	IDIVI T,TRKCYL			;T←CYLINDER, TT←HEAD
	DPB T,[POINT 16,C1CCHR,15]	;C C
	DPB TT,[POINT 8,C1CCHR,23]	;H
	MOVE TT,RECORD
	POP P,RECORD
	DPB TT,[POINT 8,C1CCHR,31]	;R
	MOVE TT,C1WCHN(N)		;GET CHANNEL NUMBER
	DPB N,[POINT 4,@C1PPTP(TT),12]	;STORE DISK DRIVE ADDRESS
	MOVEI N,4
	DPB N,[POINT 5,@C1PPTP(TT),4]	;STORE START CODE
C1WAIT:	JUMPN TT,C1WAIB
	CONSO C1A,CIF
	JRST .-1
	MOVEI T,0
	EXCH T,C1APT+C1ISW
C1WAIA:	TLC T,200000
	TLNE T,600000
	JRST C1WERR
	MOVE T,C1PH+C1STA		;STATUS A WORD
	TRNN T,C1HLT
	JRST C1WERR
	XCT C1CIFI(TT)			;CLEAR INT FLAG
	POPJ P,

C1WAIB:	CONSO C1B,CIF
	JRST .-1
	MOVEI T,0
	EXCH T,C1BPT+C1ISW
	JRST C1WAIA

C1WERR:	AOS T,C1ERR
	CAIL T,=10
	JRST C1DIE
	PUSHJ P,BLAST
	MOVEI T,4
	DPB T,[POINT 5,@C1PPTP(TT),4]		;START C1 AGAIN
	JRST C1WAIT

C1DIE:	MOVEI B,[ASCIZ /C1 ERRORS
/]
	PUSHJ P,TYPE
	JRST 4,.


C1MPIL:	PUSH P,A			;HERE WITH WCMA IN T, 1ST RECORD # IN RECORD
	PUSH P,B
	PUSH P,C
	MOVE A,[-=21,,C1MRTD-1]		;PUSH DOWN POINTER FOR DATA POINTERS
	MOVE B,RECORD
C1MPI1:	HRLZ C,RCLTAB(B)		;GET SIZE OF RECORD
	LSH C,4
	HRR C,T
	TLO C,600000			;MARK AS DATA PNTR AND 1ST OF THE RECORD
	PUSH A,C
	ADD T,RCLTAB(B)
	ADDI B,1			;ADVANCE RECORD NUMBER
	JUMPL T,C1MPI1
	MOVE T,B			;RETURN NEXT RECORD NUMBER IN T
	PUSH A,[0]
	POP P,C
	POP P,B
	POP P,A
	POPJ P,

C1SET:	SETZM C1ZERO
	MOVE A,[C1ZERO,,C1ZERO+1]
	BLT A,C1ZEND-1
	MOVEI A,253
	MOVEM A,C1APT+C1CCW
	MOVEM A,C1BPT+C1CCW
	MOVEI A,C1BW				;BUSY WAIT BIT
	MOVEM A,C1PH
	MOVE A,[C1JMP,,C1MRTC]
	MOVEM A,C1PH+C1INST
	MOVE A,[<BYTE (5)37 (8)CUADR⊗4>!C1PH]
	MOVEM A,C1APT+C1PPTR
	MOVE A,[<BYTE (5)37 (8)<CUADR+1>⊗4>!C1PH]
	MOVEM A,C1BPT+C1PPTR
	POPJ P,
>;IFE RHDSK

BLAST:
IFE RHDSK,<
;RESET C1 CHANNELS
RSTC1:	AOSN C1FRST
	PUSHJ P,C1SET				;SET UP C1 DATA AREAS ONCE ONLY
	CONO C1A,C1SBI!C1RSI!C1SRUN!C1CONT	;RESET ALL CHANNELS START CLOCK
	CONO C1A,C1SCH!C1RST!C1MPCN		;RESET CHAN A AND START UP
	CONO C1B,C1SCH!C1RST!C1MPCN		;RESET CHAN B AND START UP
	CONO C1A,C1SCH!C1SCF1!C1LCD!C1SYSR	;TELL C1A TO DO A SYSTEM RESET
	MOVEI A,100000
	CONSZ C1A,CF1				;WAIT FOR IT TO DROP CF1
	SOJG A,.-1
	CONO C1B,C1SCH!C1SCF1!C1LCD!C1SYSR	;TELL C1B TOO
	MOVEI A,100000
	CONSZ C1B,CF1
	SOJG A,.-1
	CONO C1A,C1SCH!C1SCF1!C1LCD!C1LPT	;INT THE CHANNEL FOR LD ...
	CONO C1B,C1SCH!C1SCF1!C1LCD!C1LPT	;...PGM TABLE.
	MOVEI A,100000
	CONSO C1A,CF2			;WAIT FOR CHANNEL TO BE READY FOR PGM TBL
	SOJG A,.-1
	DATAO C1A,C1PTP			;TELL IT WHERE THE PROGRAM TABLE IS
	CONO C1A,C1SCH!C1CCF1		;CLEAR CF1 (TELL IT WE'VE TOLD IT)
	MOVEI A,100000
	CONSZ C1A,CF2			;WAIT FOR CHANNEL TO DROP CF2
	SOJG A,.-1
	MOVEI A,100000
	CONSO C1B,CF2			;REPEAT FOR SECOND CHANNEL
	SOJG A,.-1
	DATAO C1B,C1PTP+1
	CONO C1B,C1SCH!C1CCF1
	MOVEI A,100000
	CONSZ C1B,CF2
	SOJG A,.-1
	POPJ P,
>;IFE RHDSK
;TYPE TYPE1 TYO CPOPJ1 CPOPJ DTEXX KLTYO KLTYI TYI KLTYI1 POPCJ TYICAN FILTYP PPNTYP TYPSIX TYPSI1 TWAIT OCTTYP OCTTY1

;TYPE, TYO, TYI, FILTYP, PPNTYP, TWAIT

TYPE:	HRLI B,440700
TYPE1:	ILDB C,B
	JUMPE C,CPOPJ
	PUSHJ P,TYO
	JRST TYPE1

TYO:	PUSH P,C
	CAIN C,33
	MOVEI C,"$"
IFN KACODE,<
	SKPKA
	SKIPE KASIM
	CAIA
>;IFN KACODE
	JRST KLTYO
IFN KACODE,<
	CONSZ TTY,20
	JRST .-1
	DATAO TTY,C
	POP P,C
	POPJ P,
>;IFN KACODE

CPOPJ1:	AOS (P)
CPOPJ:	POPJ P,


DTEXX:	MOVEM C,KLEPT+DTCMD
	SETZM KLEPT+DTFLG		;CLEAR 11'S RESPONSE FLAG
	CONO DTE0,DONG11		;RING FOR 11
	SKIPN KLEPT+DTFLG		;WAIT FOR RESPONSE
	JRST .-1
	MOVE C,KLEPT+DTF11		;GET 11'S RESPONSE WORD
	POPJ P,

KLTYO:	ANDI C,177
	PUSHJ P,DTEXX
	POP P,C
	POPJ P,

IFN DSKDSW,<

KLTYI:	MOVEI C,3400
	PUSHJ P,DTEXX
	JUMPE C,KLTYI
	JRST KLTYI1

TYI:
IFN KACODE,<
	SKPKA
	SKIPE KASIM
	CAIA
>;IFN KACODE
	JRST KLTYI
IFN KACODE,<
	CONSO TTY,40
	JRST .-1
	DATAI TTY,C
>;IFN KACODE
KLTYI1:	ANDI C,177			;FLUSH PARITY BIT
	CAIL C,"a"
	CAILE C,"z"
	CAIA
	SUBI C,40
	CAIE C,176
	CAIN C,175
	MOVEI C,33
	CAIN C,12
	MOVEI C,15
	CAIN C,"U"-100
	JRST TYICAN
	TRNE F,RBO			;SKIP UNLESS RUBBING OUT
	POPJ P,				;DON'T ECHO HERE IF RUBBING OUT
	PUSH P,C
	PUSHJ P,TYO
	CAIE C,15
	JRST POPCJ
	MOVEI C,12
	PUSHJ P,TYO
POPCJ:	POP P,C
	POPJ P,

TYICAN:	MOVEI C,"↑"
	PUSHJ P,TYO
	MOVEI C,"U"
	PUSHJ P,TYO
	MOVEI C,"U"-100
	TRZ F,RBO
	POPJ P,

FILTYP:	MOVE D,FNAM
	PUSHJ P,TYPSIX
	MOVEI C,"."
	SKIPN D,FEXT
	JRST PPNTYP
	PUSHJ P,TYO
	PUSHJ P,TYPSIX
PPNTYP:	MOVEI C,"["
	PUSHJ P,TYO
	HLLZ D,FPPN
	PUSHJ P,TYPSIX
	MOVEI C,","
	PUSHJ P,TYO
	HRLZ D,FPPN
	PUSHJ P,TYPSIX
	MOVEI C,"]"
	JRST TYO

TYPSIX:	MOVEI C,0
	LSHC C,6
	JUMPE C,TYPSI1
	ADDI C,40
	PUSHJ P,TYO
TYPSI1:	JUMPN D,TYPSIX
	POPJ P,

TWAIT:
IFN KACODE,<
	SKPKA
	SKIPE KASIM
	CAIA
	POPJ P,
	CONSZ TTY,20
	JRST TWAIT
>;IFN KACODE
	POPJ P,

OCTTYP:	IDIVI B,10
	JUMPE B,OCTTY1
	HRLM C,(P)
	PUSHJ P,OCTTYP
	HLRZ C,(P)
OCTTY1:	ADDI C,"0"
	JRST TYO
>;DSKDSW
;⊗ C1ZERO C1APT C1BPT C1PH C1ZEND C1FRST C1ERR C1PTP C1PPTP C1CIFI ZZZ C1MRTC C1CCHR C1MRTD C1WCHN RCLTAB XBUF LPDL LPDL PDL ERRCNT RECORD NXTTRK SYMPNT SYSLOC PATCH LODCNT LODNXT XFRCNT STARTA KASIM MUCKFL ZERFLG FHILOC UPPRST TIBFLN TIBUF FDEV FNAM FEXT FPPN DEFDEV DEFEXT DEFPPN

;DISK ADDRESSES AND POINTERS

IFE RHDSK,<
C1ZERO::			;ZERO FROM HERE TO C1ZEND AT DISKUP
C1APT:	BLOCK C1PPTR+1+1	;CHN CTL WD, INT WD, PGM PTR, END MARK
C1BPT:	BLOCK C1PPTR+1+1	;PROGRAM TABLE FOR SECOND CHANNEL
C1PH:	BLOCK C1INST		;PROGRAM HEADER
	0			;JUMP TO PROGRAM

C1ZEND::

C1FRST:	-1			;-1 FIRST TIME THROUGH
C1ERR:	0			;ERROR COUNT

C1PTP:	C1APT			;POINTERS TO PRG TABLES INDEXED BY CHANNEL NUMBER
	C1BPT

C1PPTP:	C1APT+C1PPTR
	C1BPT+C1PPTR

C1CIFI:	CONO C1A,C1SCH!C1CCIF		;INST TO CLEAR CIF INDEXED BY CHANNEL NUMBER
	CONO C1B,C1SCH!C1CCIF

;WCMAS FOR CONTROL COMMANDS
DEFINE C1WCMA (COUNT,ADDR,REC)<
ZZZ←←0
IFIDN <REC><R><ZZZ←←1>
BYTE (1)1 (1)ZZZ (13)COUNT (22)ADDR
>

C1MRTC:	C1MRT!C1NATM!6,,0		;MRT READ COMMAND
C1CCHR:	BYTE (8)0,0,0,0			;C C H R
	BYTE (8)0,=19-1,0,0		;SECTOR, LAST REC, WRAP REC, 0
	C1JMP,,C1MRTD			;JUMP TO 1ST DATA POINTER
C1MRTD:	BLOCK =19
	0

	'C1WCHN'	;FOR AIDING LOCATING OF THIS TABLE IN CORE FROM DDT
;TABLE OF WHICH DRIVE IS ON WHICH CHANNEL, 0 FOR C1A, 1 FOR C1B
C1WCHN:
IFN FT1DSK,<
	1
	1
	1
	1
	1
	1
	1
	1
>;IFN FT1DSK
IFE FT1DSK,<
	0
	1
	0
	1
	0
	1
	0
	1
>;IFE FT1DSK
IFN .-C1WCHN-NPACKS,<.FATAL GUESS WHAT YOU FORGOT TO CHANGE>
>;IFE RHDSK


RCLTAB:	40,,40
REPEAT =18,<
	200,,200
>

IFN DSKDSW,<
XBUF:	BLOCK 4440
>;DSKDSW

IFN DSKDSW,<
LPDL←←20
>;IFN DSKDSW
IFE DSKDSW,<
LPDL←←5
>;IFE DSKDSW
PDL:	BLOCK LPDL

ERRCNT:	0
RECORD:	0
NXTTRK:	0			;BYTE POINTER TO DPTR

SYMPNT:	0			;SYMBOL TABLE POINTER FROM DSKDMP.DMP

IFN DSKDBG,<
SYSLOC:	0			;DISK ADDRESS OF SSSYS.UFD[1,1]
PATCH:	BLOCK 40
>;DSKDBG

LODCNT:	0			;NUMBER OF WORDS IN FILE LEFT TO LOAD
LODNXT:	0			;NEXT ADDRESS TO LOAD INTO
XFRCNT:	0			;NUMBER OF WORDS THIS TRANSFER
STARTA:	0			;DSKDMP'S STARTING ADDRESS
KASIM:	0			;-1 IF KA SIMULATION UCODE IS RUNNING

IFN DSKDSW,<
MUCKFL:	0			;-1 IF MUCKING AROUND WITH LOW CORE CELLS
ZERFLG:	0			;-1 TO ZERO CORE FIRST
FHILOC:	0			;HILOC OF FILE WE ARE LOADING
UPPRST:	0			;CORE ADDRESS OF START OF UPPER

TIBFLN←←20
TIBUF:	BLOCK TIBFLN
FDEV:	0
FNAM:	0
FEXT:	0
	0
FPPN:	0
IFN RHDSK,<
DEFDEV:	SIXBIT /RSK/		;DEFAULT STRUCTURE
>;IFN RHDSK
DEFEXT:	SIXBIT /DMP/		;DEFAULT EXTENSION
DEFPPN:	SIXBIT /  SSYS/		;DEFAULT PPN
>;DSKDSW
;AC CONVENTIONS IN THIS PROGRAM:

IFN 0,< ;most of rest of file, from BOOT10, mostly

;;	SEARCH F(F.UNV[S,SYS]),S(S.UNV[S,SYS])
;;	SEARCH F,S
;;	IFN FTKL10,<
;;	SEARCH	DTEPRM
;;	>;IFN FTKL10

;
; S	- FLAGS (SEE FL.XXX, FR.XXX)
; J	- INDEX INTO DEVICE CODE TABLE
; U	- PHYSICAL UNIT NUMBER
; W	- OFFSET INTO TYPE TABLE (RH10, RH20, RH11, ETC.)
; R	- PHYSICAL OR VIRTUAL CORE ADDRESS OF START OF TRANSFER
; LB	- LOGICAL BLOCK ON UNIT OF FIRST BLOCK TO TRANSFER
; M	- NUMBER OF BLOCKS TO TRANSFER
; T1-T4	- TEMPORARIES.  NOT GUARENTEED ACROSS SUBROUTINE CALLS EXCEPT
;	  WHERE EXPLICITLY NOTED.
; P1,P2	- PRESERVED REGISTERS (ACROSS SUBROUTINE CALLS)
; P3,P4 - FILENAME, EXTENSION OF FILE BEING SEARCHED FOR. MAY
;	  NOT BE PRESERVED ACROSS ALL SUBROUTINE CALLS


S←0	;F←0
J←1	;A←1
U←2	;B←2
W←3	;C←3
R←4	;D←4
LB←5
M←6
P1←7
P2←10
P3←11
P4←12
T1←13
T2←14	;N←14
T3←15	;T←15
T4←16	;TT←16
	;P←17

;Processor type
FTKL10←←1
FTKI10←←0
FTKS10←←0

OPDEF PJRST [JRST]
OPDEF PJSP [JSP]

DEFINE EXP <>	;from Macro's expression pseudo-op, not needed in Fail

FL.RIB←←0
FL.EXR←←0
FL.IO←←0

LG.EPT←←17777	;field for Page number of EPT
;MONITOR PARAMETERS WHICH MUST AGREE WITH COMMON/COMMOD. ;⊗ HOMNAM HOMSNM HOMLUN HOMHOM HOMRXB HOMSIZ HOMFSN HOMCOD HOMSLF CODHOM RIBFIR RIBPPN RIBNAM RIBEXT RIBSIZ RIBSTS RIPDMP RIBXRA RIPNUB RIBCOD CODRIB RIBSLF BOOTSA BOOTWD LBNHOM LB2HOM LBOBAT LIMLVL MBTCOM MAXPGS .EPHSB

;RIB DEFINITIONS

RIBFIR←←0		;AOBJN POINTER TO FIRST RETRIVAL POINTER IN RIB
RIBPPN←←1		;PPN OF FILE
RIBNAM←←2		;SIXBIT FILENAME
RIBEXT←←3		;SIXBIT EXTENSION
RIBSIZ←←5		;SIZE OF FILE IN WORDS
RIBSTS←←17		;STATUS BITS
RIPDMP←←100000		;THIS FILE CONTAINS AN UNPROCESSED DUMP
RIBXRA←←34		;POINTER TO NEXT EXTENDED RIB
RIPNUB←←400000		;NEW UNIT POINTER IN RETRIEVAL POINTER
RIBCOD←←176		;CONTAINS UNLIKELY CODE
CODRIB←←777777		;THE CODE
RIBSLF←←177		;SELF BLOCK POINTER


;MISCELANEOUS DEFINITIONS

BOOTSA←←21		;PHYSICAL ADDRESS FROM WHICH BOOT LOADED THE
			;  MONITOR.  USED TO FIND MONITOR FILESPEC
BOOTWD←←22		;APRID OR CONI PAG, OF CPU ON WHICH BOOT WAS
			;  RUN.  ALSO USED AS CHANNEL COMMAND PAIR FOR
			;  RH10'S.
LBNHOM←←1		;BLOCK ADDRESS OF FIRST HOME BLOCK
LB2HOM←←12		;BLOCK ADDRESS OF SECOND HOME BLOCK
LBOBAT←←1		;OFFSET OF BAT BLOCK FROM HOME BLOCK
LIMLVL←←5		;NUMBER OF SFD'S
MBTCOM←←411		;COMMUNICATIONS WORD IN LOW CORE FOR REBOOT
			;REQUESTS.  CONTAINS THE PHYSICAL PAGE NUMBER
			;OF WHERE TO PUT BOOT DURING REBOOT PROCESSING
MAXPGS←←<FTKI10&=8192>!<FTKL10&=8192>!<FTKS10&=1024>
			;MAXIMUM NUMBER OF PAGES POSSIBLE IN MEMORY
.EPHSB←←424		;KS10 HALT STATUS BLOCK ADDRESS
;MISCELANEOUS HARDWARE PARAMETERS ;⊗ IT.DON IT.BSY APRRST CLRAPR PDLLEN LINBFL BLKSIZ PAGSIZ MAXUNI P2BLSH B2WLSH W2BLSH P2WLSH W2PLSH .VBOOT .VPAG0 .VMOVE .VZERO .MBOOT .MPAG0 .MMOVE .MZERO

IT.DON←←1B30		;KI10 CONI CTY, INPUT DONE
IT.BSY←←1B31		;KI10 CONI CTY, OUTPUT BUSY
APRRST←←<FTKI10&321300>!<FTKL10&327760>!<FTKS10&221700>
			;CONO BITS TO CLEAR THE WORLD
CLRAPR←←<FTKI10&300>!<FTKL10&127700>!<FTKS10&021700>
			;CONO BITS TO CLEAR APR ERROR FLAGS


;MISCELANEOUS PARAMETERS

PDLLEN←←=36		;SIZE OF PDL
LINBFL←←=16		;SIZE OF COMMAND LINE BUFFER IN WORDS
BLKSIZ←←200		;SIZE OF A DISK BLOCK
PAGSIZ←←1000		;SIZE OF A PAGE
MAXUNI←←=8		;MAX NUMBER OF UNITS ON A CONTROLLER
P2BLSH←←2		;AMOUNT TO LSH A PAGE COUNT TO GET BLOCKS
B2WLSH←←=7		;AMOUNT TO LSH A BLOCK COUNT TO GET WORDS
W2BLSH←←-B2WLSH		;AMOUNT TO LSH A WORD COUNT TO GET BLOCKS
P2WLSH←←=9		;AMOUNT TO LSH A PAGE NUMBER TO GET WORDS
W2PLSH←←-P2WLSH		;AMOUNT TO LSH A WORD COUNT TO GET PAGES

.VBOOT←←750000		;VIRTUAL ADDRESS AT WHICH MOST OF BOOT
			;  RUNS (AFTER CALL TO SETUP)
.VPAG0←←730000		;PAGE 0 MAPPED THROUGH THIS VIRUAL ADDRESS
			;PAGE 1 MAPPED THROUGH .VPAG0+PAGSIZ
.VMOVE←←732000		;FIRST VIRTUAL ADDRESS USED TO MOVE BOOT TO
			;  HIGH CORE
.VZERO←←732000		;VIRTUAL ADDRESS USED TO ZERO CORE


DEFINE	VMAP(ADDR),<<ADDR/PAGSIZ>/2>

.MBOOT←←VMAP(.VBOOT)	;LEFT HALF WORD IN EPT MAPPING .VBOOT
.MPAG0←←VMAP(.VPAG0)	;LEFT HALF WORD IN EPT MAPPING .VPAG0
			;RIGHT HALF WORD MAPS .VPAG0+PAGSIZ
.MMOVE←←VMAP(.VMOVE)	;LEFT HALF WORD IN EPT MAPPING .VMOVE
.MZERO←←VMAP(.VZERO)	;LEFT HALF WORD IN EPT MAPPING .VZERO
IFN FTKL10!FTKI10,< ;⊗ CI.XDN CI.122 CI.1ER CI.1RA CI.2ER CI.2RA CO.XDN CO.XSX CO.XMI CO.1RB CO.1AE CO.2RB CO.2ME DO.XCR DO.XSR DI.XCE DI.XSM DI.XSB DO.XDS DO.XDT DO.XDC DO.1CR DO.2ST DO.XCL DO.XRP DO.XRD DO.XWT RH2TRA RH2JMP R2IOWL R2BCNT R2WCNT R1BCNT R1WCNT

;RH10/RH20 DEVICE DEPENDENT PARAMETERS

;CONI BITS
CI.XDN←←10		;TRANSFER DONE (RH10/RH20)
CI.122←←<4000,,0>	;22 BIT CHANNEL (RH10/DF10C)
CI.1ER←←736320		;DBPE, FXCEP, CHNER, OVR, DRE, ILC, PSFAIL,
			;CBOV, RAE, BUSY (RH10)
CI.1RA←←100		;RAE (RH10)
CI.2ER←←515000		;DPE, LWCE, DR, RAE, DOE (RH20)
CI.2RA←←4000		;RAE (RH20)

;CONO BITS
CO.XDN←←10		;CLEAR DONE (RH10/RH20)
CO.XSX←←20		;STOP TRANSFER (RH10/RH20)
CO.XMI←←2000		;MASSBUS INIT (RH10/RH20)
CO.1RB←←47		;CONI BITS TO RESTORE - AIE, PIA (RH10)
CO.1AE←←40		;AIE (RH10)
CO.2RB←←447		;CONI BITS TO RESTORE - MBE, AIE, PIA (RH20)
CO.2ME←←400		;MASSBUS ENABLE (RH20)

;DATAI/DATAO BITS

DO.XCR←←<004400,,0>	;DRIVE CONTROL REGISTER (RH10/RH20)
DO.XSR←←<010400,,0>	;STATUS REGISTER (RH10/RH20)
  DI.XCE←←40000		;COMPOSITE ERROR (RH10/RH20)
  DI.XSM←←172777	;BIT MASK OF BITS TO CHECK FOR IN INITIALIZATION
  DI.XSB←←10700		;LEGAL VALUE IN SR (MOL, DP, DR, VV)
DO.XDS←←<054000,,0>	;BLOCK ADDRESS REGISTER, LR (RH10/RH20)
DO.XDT←←<060000,,0>	;DRIVE TYPE REGISTER (RH10/RH20)
DO.XDC←←<124000,,0>	;DESIRED CYLINDER REGISTER, LR (RH10/RH20)
DO.1CR←←<404000,,0>	;CONTROL REGISTER (RH10)
DO.2ST←←<716200,,0>	;STCR, LR, RCLP, STORE (RH20)
DO.XCL←←11		;FUNCTION CODE FOR DRIVE CLEAR (RH10/RH20)
DO.XRP←←21		;FUNCTION CODE FOR READIN PRESET (RH10/RH20)
DO.XRD←←71		;FUNCTION CODE FOR READ (RH10/RH20)
DO.XWT←←61		;FUNCTION CODE FOR WRITE (RH10/RH20)

;MISCELANEOUS

RH2TRA←←1B0		;CHANNEL COMMAND OPCODE FOR TRANSFER (RH20)
RH2JMP←←1B1		;CHANNEL COMMAND OPCODE FOR JUMP (RH20)
R2IOWL←←=69		;NUMBER OF IOWDS TO ALLOCATE FOR THE LARGEST
			;POSSIBLE TRANSFER
R2BCNT←←=15		;MAX NUMBER OF BLOCKS WHICH MAY BE SPECIFIED
			;IN ONE IOWD FOR AN RH20
R2WCNT←←R2BCNT*BLKSIZ	;CORRESPONDING WORDCOUNT
R1BCNT←←=127		;MAX NUMBER OF BLOCKS WHICH MAY BE SPECIFIED
			;IN ONE IOWD FOR AN RH10
R1WCNT←←R1BCNT*BLKSIZ	;CORRESPONDING WORDCOUNT

>;END IFN FTKL10!FTKI10
IFN FTKS10,< ;⊗ SO.UPR SO.VFT SO.RBT SO.USR SO.UBI SI.UER SO.CS1 SI.RDY SI.S1E SO.WC SO.BA SO.DA SO.CS2 SO.DS SO.DSM SO.DSB SI.DT SI.DSK SO.DC SO.DCL SO.RIP SO.WRT SO.RED RSBCNT

;RH11 DEVICE DEPENDENT PARAMETERS

;UBA ADDRESSES/BITS

SO.UPR←←763000		;UBA PAGING RAM ADDRESS
  SO.VFT←←140000	;VALID+FAST XFER
  SO.RBT←←<100,,277>	;BITS TO RESTORE IN CS1 AND UBA SR
SO.USR←←763100		;UBA STATUS REGISTER
  SO.UBI←←100		;UNIBUS INIT
  SI.UER←←740000	;TIME OUT, BMD, BUS PAR, NXD

;DRIVE ADDRESSES/BITS

SO.CS1←←776700		;CONTROL STATUS REGISTER 1
  SI.RDY←←200		;READY AT END OF XFER
  SI.S1E←←140000	;SC, TRE
SO.WC←←776702		;WORD COUNT REGISTER
SO.BA←←776704		;BUS ADDRESS REGISTER
SO.DA←←776706		;DESIRED ADDRESS REGISTER
SO.CS2←←776710		;CONTROL STATUS REGISTER 2
SO.DS←←776712		;DRIVE STATUS REGISTER
  SO.DSM←←172700	;MASK FOR BITS RETURNED
  SO.DSB←←10700		;LEGAL VALUE (MOL, DP, DR, VV)
SI.DT←←776726		;DRIVE TYPE REGISTER
  SI.DSK←←20000		;DEVICE IS A DISK
SO.DC←←776734		;DESIRED CYLINDER REGISTER

;MISCELLANEOUS

SO.DCL←←11		;FUNCTION CODE FOR DRIVE CLEAR
SO.RIP←←21		;FUNCTION CODE FOR READIN PRESET
SO.WRT←←61		;FUNCTION CODE FOR WRITE
SO.RED←←71		;FUNCTION CODE FOR READ

RSBCNT←←=252		;MAX NUMBER OF BLOCKS WHICH MAY BE TRANSFERED
			;AT ONE TIME BY THE RH11

>;END IFN FTKS10
;MACROS TO HELP IN INSERTING ENTRIES INTO THE PAGE MAP ; BLK STALL

;MACRO TO CAUSE A PAUSE BETWEEN THE DATAO WHICH LOADS THE PREPARATION
;REGISTER AND THE DATAI WHICH READS THE VALUE FROM THE SPECIFIED
;REGISTER.

	DEFINE	STALL,<
	  IMULI	P,1
	  IFN FTKL10,<
	  XLIST
	  IMULI P,1
	  LIST
	  >
	>

DEFINE BLK(NAME,SIZE)<
NAME: BLOCK SIZE>
BLK(HOM,BLKSIZ)		;HOM BLOCK FOR CURRENT UNIT ;⊗ SWTVLV SWTVLL FILSPE NXMTBE
BLK(RIB,BLKSIZ)		;RIB BLOCK FOR CURRENT FILE
BLK(BUF,BLKSIZ)		;WORK BUFFER

;THE FOLLOWING LOCATIONS MUST REMAIN IN THIS ORDER.  (SEE BOOTFX IN ONCE)

BLK(FILSPC,0)		;FIRST WORD CLEARED EACH TIME THROUGH PARSE
BLK(DEV,1)		;DEVICE NAME
BLK(FILNAM,1)		;FILENAME
BLK(EXT,1)		;EXTENSION
BLK(PTHBLK,7)		;PATH BLOCK

;END OF ORDER DEPENDENT LOCATIONS


SWTVLV:
BLK(SWTVAL,0)		;START OF BLOCK OF SWITCH VALUES
BLK(STSA,1)		;START ADDRESS GIVEN IN /START
SWTVLL←←.-SWTVLV
FILSPE←←.-1		;END OF AREA TO CLEAR EACH TIME THROUGH PARSE

BLK(EPTADR,1)		;PHYSICAL ADDRESS OF OUR EPT
BLK(CPEBR,1)		;ARGUMENT TO CHANGE THE EPT TO IT'S CURRENT VALUE
BLK(MEMPSZ,1)		;NUMBER OF PAGES IN MEMORY
BLK(LUNPOS,1)		;LOGICAL UNIT NUMBER WITHIN STR
BLK(DRVBPC,1)		;BLOCKS/CYLINDER ON THIS UNIT \*** KEEP
BLK(DRVBPT,1)		;BLOCKS/TRACK ON THIS UNIT    /*** TOGETHER
BLK(BLKCNT,1)		;NUMBER BLOCKS LEFT IN THIS GROUP
BLK(BLKADR,1)		;CURRENT BLOCK ADDRESS
BLK(BLKNUM,1)		;CURRENT RELATIVE BLOCK NUMBER IN FILE
BLK(SAVFIR,1)		;COPY OF RIBFIR FROM CURRENT RIB
BLK(SAVSIZ,1)		;COPY OF RIBSIZ FROM CURRENT RIB
BLK(BTSPDL,PDLLEN)	;PUSH DOWN LIST
BLK(CMDPTR,1)		;BYTE POINTER TO COMMAND BUFFER
BLK(CMDBUF,LINBFL)	;COMMAND LINE BUFFER
BLK(NXMTAB,<MAXPGS/=36>+1) ;OUR COPY OF NXMTAB
NXMTBE←←.-1		;END OF NXMTAB
	SUBTTL	BLOCK READ/WRITE SUBROUTINES ;⊗ WRTRIB WRTBUF REDBUF


;ROUTINE TO WRITE BUF/RIB TO THE OUTPUT FILE.  CALL WITH RIB OF FILE
;SETUP.
;CALL:	PUSHJ	P,WRTBUF  -OR-  PUSHJ P,WRTRIB
;RETURN+1 IF ERROR DETECTED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL

WRTRIB:	MOVEI	R,RIB		;POINT TO RIB
	AOS	SAVSIZ		;COMPENSATE FOR SELBLK DECREMENTING SAVSIZ
	TLZA	S,(FL.RIB)	;FORCE SELBLK TO WRITE THE RIB
WRTBUF:	MOVEI	R,BUF		;POINT TO BUF
	MOVEI	T1,1		;NUMBER OF BLOCKS IS 1
	PUSHJ	P,SELBLK	;SETUP TO DO THAT MANY
	  JRST	EOFERR		;FILE MUST BE REALLY SCREWED UP
	JUMPN	T1,EOFERR	;DITTO
	PUSHJ	P,VRTWRT	;WRITE THE BLOCK
	  JRST	IOFERR		;WRITE ERROR
	JRST	CPOPJ1		;GIVE SKIP RETURN


;ROUTINE TO READ ONE BLOCK FROM THE INPUT FILE INTO BUF.  CALL WITH
;RIB OF FILE SETUP.
;CALL:	PUSHJ	P,REDBUF
;RETURN+1 IF ERROR DETECTED WITH ERROR CODE IN T1
;RETURN+2 IF SUCCESSFUL

REDBUF:	MOVEI	R,BUF		;POINT TO BUF
	MOVEI	T1,1		;NUMBER OF BLOCKS IS 1
	PUSHJ	P,SELBLK	;SETUP TO READ
	  JRST	EOFERR		;HIT EOF
	JUMPN	T1,EOFERR	;DITTO
	PUSHJ	P,VRTRED	;READ THE BLOCK
	  JRST	IOFERR		;READ ERROR
	JRST	CPOPJ1		;GIVE SKIP RETURN
;ROUTINE TO FIND A UNIT AND READ IT'S HOM BLOCK. CALL WITH LUNPOS ;⊗ FNDLUN FNDUNI FNDUN1 FNDUN2 FNDUN3
;CONTAINING THE LOGICAL UNIT NUMBER AND DEV CONTAINING THE DEVICE
;NAME.
;CALL:
;	T1/LOGICAL UNIT IN STRUCTURE
;	PUSHJ	P,FNDLUN
;RETURN+1 IF NOT FOUND
;RETURN+2 IF FOUND WITH HOM BLOCK IN HOM

FNDLUN:	EXCH	T1,LUNPOS	;STORE UNIT, GET CURRENT
	CAMN	T1,LUNPOS	;SAME AS CURRENT ONE?
	JRST	CPOPJ1		;YES, ALREADY THERE
;;	PJRST	FNDUNI		;FALL INTO FNDUNI


;ROUTINE TO FIND A UNIT BY EXHAUSTIVE SEARCH.  CALL WITH LUNPOS
;CONTAINING THE LOGICAL UNIT NUMBER IN THE STRUCTURE, DEV CONTAINING
;THE STRUCTURE NAME AND SDLPOS CONTAINING THE POSITION IN THE SYSTEM
;DUMP LIST.
;CALL:	PUSHJ	P,FNDUNI
;RETURN+1 IF NOT FOUND
;RETURN+2 IF FOUND WITH HOM BLOCK IN HOM

FNDUNI:	MOVSI	J,-DVCTBL	;AOBJN POINTER TO DEVICE CODE TABLE
FNDUN1:	MOVSI	U,-MAXUNI	;AOBJN POINTER FOR EACH UNIT
FNDUN2:	HLRZ	W,DVCTAB(J)	;SETUP TYPE OFFSET
	PUSHJ	P,SETIOT	;SETUP I/O INSTRUCTIONS
	PUSHJ	P,REDHOM	;READ HOM BLOCK FOR UNIT
	  JRST	FNDUN3		;FAILED OR BAD
	MOVE	T1,HOM+HOMLUN	;GET LOGICAL UNIT NUMBER OF THIS STR
	MOVE	T2,HOM+HOMSNM	;GET STR NAME
	CAMN	T1,LUNPOS	;UNIT NUMBER MATCH?
	CAME	T2,DEV		;YES, DOES IT?
	JRST	FNDUN3		;NO
	JRST	CPOPJ1		;YES, GIVE SKIP RETURN
FNDUN3:	AOBJN	U,FNDUN2	;LOOP FOR NEXT UNIT
	AOBJN	J,FNDUN1	;LOOP FOR NEXT CONTROLLER
	POPJ	P,		;ERROR RETURN
;ROUTINE TO READ A HOM BLOCK. ;⊗ REDHOM REDHO1 REDHO2
;CALL:
;	U/PHYSICAL UNIT NUMBER
;	J/OFFSET INTO DEVICE CODE TABLE
;	W/OFFSET INTO TYPE TABLES
;	PUSHJ	P,REDHOM
;RETURN+1 IF ERROR
;RETURN+2 IF SUCCESSFUL WITH HOM BLOCK IN HOM

REDHOM:	MOVEI	R,HOM		;ADDRESS OF WHERE TO PUT IT
	MOVEI	LB,LBNHOM	;ADDRESS OF FIRST HOM BLOCK ON UNIT
	MOVEI	M,1		;READ 1 BLOCK
REDHO1:	PUSHJ	P,VRTRED	;READ THE BLOCK
	  JRST	REDHO2		;FAILED, TRY SECOND
	MOVS	T1,HOM+HOMNAM	;GET FIRST WORD OF BLOCK
	MOVE	T2,HOM+HOMCOD	;GET WORD CONTAINING UNLIKELY CODE
	CAIN	T1,'HOM'	;NAME MUST BE HOM
	CAIE	T2,CODHOM	;AND MUST MATCH UNLIKELY CODE
	JRST	REDHO2		;ONE FAILED
	CAMN	LB,HOM+HOMSLF	;SELF POINTER MUST MATCH
	SKIPE	HOM+HOMREF	;AND MUST NOT NEED REFRESHING
	JRST	REDHO2		;FAILED
	MOVEI	T1,T4		;SETUP HOMCLP AND
	HRRM	T1,HOM+HOMCLP	;  HOMCNP TO POINT
	HRRM	T1,HOM+HOMCNP	;  TO T4
	JRST	CPOPJ1		;GIVE SKIP RETURN
REDHO2:	CAIN	LB,LBNHOM	;DOING FIRST HOM BLOCK?
	POPJ	P,		;NO, GIVE FAIL RETURN
	MOVEI	LB,LB2HOM	;GET ADDRESS OF 2ND
	JRST	REDHO1		;AND TRY THAT ONE
;ROUTINE TO SETUP A TRANSFER TO/FROM DISK. ;⊗ SELBLK SELBL1 SELBL2 SELBL3
;CALL:
;	T1/NUMBER OF BLOCKS DESIRED TO TRANSFER
;	PUSHJ	P,SELBLK
;RETURN+1 IF EOF DETECTED
;RETURN+2 IF SOME TRANSFER IS POSSIBLE
;RETURNS M/NUMBER OF BLOCKS POSSIBLE, T1/NUMBER OF BLOCKS IN REQUEST
;	 THAT COULDN'T BE TRANSFERED, LB/BLOCK ON UNIT OF FIRST BLOCK.
;PRESERVES P3-P4

SELBLK:	TLNN	S,(FL.RIB)	;WANT TO SKIP FIRST RIB BLOCK?
	JRST	SELBL1		;NO
	PUSHJ	P,SAVE2		;SAVE P1-P2
	MOVE	P1,T1		;SAVE REQUESTED TRANSFER IN P1
	MOVEI	T1,1		;AND MAKE IT LOOK LIKE 1 BLOCK
SELBL1:	SKIPLE	BLKCNT		;AND MORE BLOCKS LEFT IN GROUP?
	JRST	SELBL4		;YES, USE THEM
SELBL2:	SKIPL	T2,SAVFIR	;RUN OUT OF POINTERS?
	JRST	SELBL5		;YES, CHECK FOR EXTENDED RIBS
	MOVE	T4,RIB(T2)	;GET NEXT POINTER
	AOBJN	T2,.+1		;INCREMENT POINTER TO POINTERS
	MOVEM	T2,SAVFIR	;STORE POINTER BACK
	LDB	T2,HOM+HOMCNP	;GET CLUSTER COUNT FROM THIS POINTER
	JUMPN	T2,SELBL3	;GO IF NON-ZERO
	TRZN	T4,RIPNUB	;UNIT CHANGE POINTER?
	POPJ	P,		;NO, THAT'S AN EOF POINTER
	PUSH	P,T1		;SAVE ARGUMENT
	MOVE	T1,T4		;COPY NEW UNIT NUMBER
	PUSHJ	P,FNDLUN	;FIND IT AND SETUP HOM BLOCK
	  JRST	TPOPJ		;NOT THERE, SIMULATE EOF
	POP	P,T1		;RESTORE ARGUMENT
	JRST	SELBL2		;TRY WITH NEXT POINTER
SELBL3:	IMUL	T2,HOM+HOMBPC	;COMPUTE NUMBER OF BLOCKS IN GROUP
	SKIPL	SAVFIR		;DOING LAST POINTER IN THIS RIB?
	SUBI	T2,1		;YES, DON'T OVERWRITE SPARE RIB
	TLNE	S,(FL.RIB)	;SKIPPING A RIB?
	AOS	SAVSIZ		;YES, FILE IS 1 MORE BLOCK LONG
	CAMLE	T2,SAVSIZ	;MORE THAN AMOUNT REMAINING IN FILE?
	MOVE	T2,SAVSIZ	;YES, USE THAT
	MOVEM	T2,BLKCNT	;STORE IT
	LDB	T2,HOM+HOMCLP	;GET CLUSTER ADDRESS OF 1ST CLUSTER IN GROUP
	IMUL	T2,HOM+HOMBPC	;COMPUTE BLOCK ADDRESS
	MOVEM	T2,BLKADR	;STORE ADDRESS OF BLOCK


				;CONTINUED ON THE NEXT PAGE
SELBL4:	MOVN	M,T1		;GET -VE NUMBER OF BLOCKS IN REQUEST ;⊗ SELBL4 SELBL5 SELBL6
	SUB	T1,BLKCNT	;SUBTRACT AMOUNT LEFT IN GROUP
	SKIPLE	T1		;REQUEST LARGER THAN AMOUNT WE HAVE?
	MOVN	M,BLKCNT	;YES, USE WHAT WE HAVE
	ADDM	M,BLKCNT	;DECREASE BLKCNT BY APPROPRIATE AMOUNT
	ADDM	M,SAVSIZ	; AND SIZE OF FILE
	MOVNS	M		;SET M TO AMOUNT TO TRANSFER
	MOVE	LB,BLKADR	;START AT THIS BLOCK
	ADDM	M,BLKADR	;INCREMENT BLOCK ADDRESS FOR NEXT CALL
	TLNN	S,(FL.RIB)	;SKIPING A RIB?
	ADDM	M,BLKNUM	;NO, UPDATE RELATIVE FILE BLOCK
	SKIPGE	T1		;CAN WE DO THE WHOLE REQUEST?
	MOVEI	T1,0		;YES, RETURN ZERO AS REMAINDER
	TLZN	S,(FL.RIB)	;SKIPPING 1 BLOCK FOR RIB?
	JRST	CPOPJ1		;NO, RETURN TO CALLER
	MOVE	T1,P1		;RESTORE ORIGINAL REQUEST
	JRST	SELBL1		;AND DO THE REAL REQUEST
SELBL5:	SKIPN	RIB+RIBXRA	;EXTENDED RIB POINTER?
	POPJ	P,		;NO, GIVE EOF RETURN
	PUSH	P,T1		;SAVE ARGUMENT
	PUSH	P,P3		;AND QUASI-PRESERVED REGISTERS
	PUSH	P,P4		;SMASHED BY REDRIB
	LDB	T1,DEYRBU	;GET UNIT ON WHICH NEXT RIB EXISTS
	PUSHJ	P,FNDLUN	;FIND UNIT, SETUP HOM BLOCK
	  JRST	SELBL6		;FAILED GIVE EOF RETURN
	LDB	LB,DEYRBA	;GET CLUSTER ADDRESS ON THAT UNIT
	IMUL	LB,HOM+HOMBPC	;CONVERT TO BLOCK ADDRESS
	TLO	S,(FL.EXR)	;DON'T CHANGE SAVSIZ FOR EXTENDED RIBS
	PUSHJ	P,REDRIB	;READ NEW RIB
	  JRST	SELBL6		;FAILED, GIVE EOF RETURN
	POP	P,P4		;RESTORE P4 AND
	POP	P,P3		;  P3
	POP	P,T1		;RESTORE ARGUMENT
	JRST	SELBLK		;AND TRY NEW POINTER FROM THIS RIB
SELBL6:	TLZ	S,(FL.EXR)	;MAKE SURE THIS FLAG IS OFF
IFN FTKL10!FTKS10,<
	ADJSP	P,-3		;BRING STACK INTO SYNC
>
IFN FTKI10,<
	SUB	P,[3,,3]	;HARDER FOR THE KI10
>
	POPJ	P,		;AND GIVE NON-SKIP RETURN
	SUBTTL	SUPPORT SUBROUTINES ;⊗ CLRBUF SETIOT ERRTAB SNTERR FNTERR UPDERR EOFERR IOFERR BDFERR MCCERR NSSERR ERRTBL ALLERR


;ROUTINE TO CLEAR BUF.
;CALL:	PUSHJ	P,CLRBUF	
;RETURN+1 ALWAYS

CLRBUF:	SETZM	BUF		;CLEAR FIRST WORD
	MOVE	T1,[BUF,,BUF+1]	;SETUP FOR BLT
	BLT	T1,BUF+BLKSIZ-1 ;CLEAR IT ALL
	POPJ	P,		;RETURN


;ROUTINE TO STORE A DEVICE CODE IN ALL I/O INSTRUCTIONS.
;CALL:
;	J/OFFSET INTO DEVICE CODE TABLE
;	PUSHJ	P,SETIOT
;RETURN+1 ALWAYS

SETIOT:
IFN FTKL10!FTKI10,<
	HRRZ	T1,DVCTAB(J)	;GET DEVICE CODE
	MOVSI	T2,-IOTTBL	;BUILD AOBJN POINTER TO IOTTAB
	DPB	T1,[POINT 7,IOTTAB(T2),9] ;STORE DEVICE CODE IN INSTN.
	AOBJN	T2,.-1		;DO THEM ALL
>
	POPJ	P,		;RETURN


;RETURN POINTS TO SET T1 TO AN ERROR CODE AND NON-SKIP RETURN

ERRTAB:
SNTERR:	PJSP	T1,ALLERR	;STRUCTURE NOT FOUND
FNTERR:	PJSP	T1,ALLERR	;FILE NOT FOUND
UPDERR:	PJSP	T1,ALLERR	;UNPROCESSED DUMP
EOFERR:	PJSP	T1,ALLERR	;UNEXPECTED EOF
IOFERR:	PJSP	T1,ALLERR	;I/O ERROR
BDFERR:	PJSP	T1,ALLERR	;BAD DIRECTORY FORMAT
MCCERR:	PJSP	T1,ALLERR	;MEM CONFIG TOO COMPLICATED
NSSERR:	PJSP	T1,ALLERR	;NOT SYSTEM SLEEP DUMP
ERRTBL←←.-ERRTAB
ALLERR:	SUBI	T1,ERRTAB+1	;COMPUTE ERROR CODE
	TLZ	T1,-1		;CLEAR LH JUNK
	POPJ	P,		;RETURN
;ROUTINE TO READ DATA INTO A VIRTUAL ADDRESS. ;⊗ VRTRED VRTWRT MAPADR
;CALL:
;	R/VIRTUAL ADDRESS
;	M/NUMBER OF BLOCKS TO TRANSFER
;	LB/BLOCK ON UNIT
;	U/PHYSICAL UNIT
;	W/OFFSET INTO TYPE TABLE
;	J/OFFSET INTO DEVICE CODE TABLE
;	PUSHJ	P,VRTRED
;RETURN+1 IF ERROR
;RETURN+2 IF SUCCESSFUL

VRTRED:	PUSHJ	P,MAPADR	;CONVERT VIRTUAL TO PHYSICAL ADDRESS
	PJRST	@REDTAB(W)	;DO THE TRANSFER


;ROUTINE TO WRITE DATA FROM A VIRTUAL ADDRESS.  CALL WITH SAME ARGUMENTS
;AS VRTRED.
;CALL:	PUSHJ	P,VRTWRT
;RETURN+1 IF ERROR
;RETURN+2 IF SUCCESSFUL

VRTWRT:	PUSHJ	P,MAPADR	;CONVERT VIRTUAL TO PHYSICAL ADDRESS
	PJRST	@WRTTAB(W)	;DO THE TRANSFER


;ROUTINE TO CONVERT A VIRTUAL ADDRESS TO A PHYSICAL ADDRESS.
;CALL:
;	R/VIRTUAL ADDRESS
;	PUSHJ	P,MAPADR
;RETURN+1 ALWAYS WITH PHYSICAL ADDRESS IN R

MAPADR:
IFN FTKI10,<
	PUSH	P,R		;SAVE VIRTUAL ADDRESS
	ANDI	R,PAGSIZ-1	;KEEP ONLY OFFSET IN PAGE
	EXCH	R,0(P)		;STORE THAT, GET FULL ADDRESS
>
	MAP	R,(R)		;CONVERT TO PHYSICAL ADDRESS
IFN FTKI10,<
	LSH	R,P2WLSH	;CONVERT PAGE NUMBER TO ADDRESS
	IOR	R,0(P)		;INCLUDE OFFSET IN PAGE
	POP	P,(P)		;FLUSH STACK
	TLZ	R,(¬<PG.EPT*PAGSIZ+PAGSIZ-1>) ;KEEP ONLY ADDRESS
>
IFN FTKL10,<
	TLZ	R,(¬<LG.EPT*PAGSIZ+PAGSIZ-1>) ;KEEP ONLY ADDRESS
>
IFN FTKS10,<
	TLZ	R,(¬<SG.EPT*PAGSIZ+PAGSIZ-1>) ;KEEP ONLY ADDRESS
>
	POPJ	P,		;AND RETURN
;ROUTINE TO SAVE P1 AND P2 AND CALL THE CALLER AS A COROUTINE ;⊗ SAVE2 SAVFR
;WHICH RESTORES P1 AND P2 WHEN THE CALLER RETURNS.
;CALL:	PUSHJ	P,SAVE2
;RETURN+1 ALWAYS

SAVE2:	EXCH	P1,(P)		;GET RETURN, SAVE P1
	PUSH	P,P2		;SAVE P2
	MOVEM	P1,1(P)		;SAVE RETURN
	MOVE	P1,-1(P)	;RESTORE P1
	PUSHJ	P,@1(P)		;CALL CALLER
	  CAIA			;NON SKIP
	AOS	-2(P)		;SKIP RET
	POP	P,P2		;RESTORE P2
	POP	P,P1		;RESTORE P1
	POPJ	P,		;RETURN


;ROUTINE TO SAVE LB AND R AND CALL THE CALLER AS A COROUTINE
;WHICH RESTORES LB AND R WHEN THE CALLER RETURNS.
;CALL:	PUSHJ	P,SAVFR
;RETURN+1 ALWAYS
SAVFR:	EXCH	LB,(P)		;GET RETURN, SAVE LB
	PUSH	P,R		;SAVE R
	MOVEM	LB,1(P)		;SAVE RETURN
	MOVE	LB,-1(P)	;RESTORE LB
	PUSHJ	P,@1(P)		;CALL CALLER
	  CAIA			;NON SKIP
	AOS	-2(P)		;SKIP RET
	POP	P,R		;RESTORE R
	POP	P,LB		;RESTORE LB
	POPJ	P,		;RETURN
	SUBTTL	DISK SUPPORT SUBROUTINES ;⊗ REDREG DRVTYP DRVTY1


IFE FTKS10,<
;ROUTINE TO READ A MASSBUS REGISTER AND RETURN THE VALUE.
;CALL WITH:
;	T1/DATAO WORD
;	PUSHJ	P,REDREG
;RETURN+1 ALWAYS WITH FULL 36 BIT DATA IN T1

REDREG:	XCT	DODATO		;TELL THE DEVICE WHICH REGISTER
	STALL			;WAIT AWHILE
	XCT	DODATI		;READ THE DATA
	POPJ	P,		;RETURN
>;END IFE FTKS10


;ROUTINE TO READ AND CHECK THE DRIVE TYPE REGISTER FOR A DEVICE AGAINST
;THOSE DRIVE TYPES THAT WE KNOW ABOUT.
;CALL:
;	T1/DATAO WORD TO READ DRIVE TYPE REGISTER
;	PUSHJ	P,DRVTYP
;RETURN+1 IF NO MATCH
;RETURN+2 IF MATCH WITH DRVBPC, DRVBPT SETUP

DRVTYP:
IFE FTKS10,<
	PUSHJ	P,REDREG	;READ THE REGISTER
>
IFN FTKS10,<
	TRNN	T1,SI.DSK	;THIS A DISK UNIT?
	POPJ	P,		;NO
>
	ANDI	T1,777		;KEEP ONLY 9 BITS
	MOVSI	T2,-DRTTBL	;GET AOBJN POINTER TO DRIVE TYPE TABLE
DRVTY1:	CAME	T1,DRTTAB(T2)	;MATCH WITH THIS ONE?
	AOBJN	T2,DRVTY1	;NO, LOOP
	JUMPGE	T2,CPOPJ	;FAIL IF NO MATCH
	MOVE	T1,BPCTAB(T2)	;GET BLOCKS/CYLINDER
	MOVE	T2,BPTTAB(T2)	;  AND BLOCKS/TRACK
	DMOVEM	T1,DRVBPC	;STORE VALUES
	JRST	CPOPJ1		;GIVE SKIP RETURN
;TABLES DEFINING THE DRIVE TYPES OF THE DRIVES WE KNOW ABOUT AND ;⊗ DRTTAB DRTTBL BPCTAB BPTTAB
;THE CORRESPONDING VALUES OF BLOCKS/CYLINDER AND BLOCKS/TRACK FOR
;EACH DRIVE.  THESE ARE PARALLEL TABLES AND THUS ARE ORDER SENSITIVE.
;
;TABLE GIVING THE DRIVE TYPES THAT WE KNOW ABOUT.

DRTTAB:	EXP	20		;RP04
	EXP	22		;RP06
	EXP	24		;RM03
	EXP	42		;RP07
DRTTBL←←.-DRTTAB


;TABLE GIVING THE NUMBER OF BLOCKS/CYLINDER FOR EACH DRIVE.

BPCTAB:	DEC	380		;RP04
	DEC	380		;RP06
	DEC	150		;RM03
	DEC	1376		;RP07


;TABLE GIVING THE NUMBER OF BLOCKS/TRACK FOR EACH DRIVE.

BPTTAB:	DEC	20		;RP04
	DEC	20		;RP04
	DEC	30		;RM03
	DEC	43		;RP07
	SUBTTL	BYTE POINTERS INTO DATA STRUCTURES ;⊗ DESRBU DENRBU DESRBA DENRBA DEYRBU DEYRBA


DESRBU←←=4	;SIZE OF UNIT NUMBER FIELD IN RIBXRA
DENRBU←←=12	;BIT POSITION OF UNIT NUMBER FIELD IN RIBXRA
DESRBA←←=23	;SIZE OF CLUSTER ADDRESS FIELD IN RIBXRA
DENRBA←←=35	;BIT POSITION OF CLUSTER ADDRESS FIELD IN RIBXRA

DEYRBU:	POINT	DESRBU,RIB+RIBXRA,DENRBU
		;UNIT ON WHICH NEXT EXTENDED RIB EXISTS
DEYRBA:	POINT	DESRBA,RIB+RIBXRA,DENRBA
		;CLUSTER ADDRESS ON UNIT ON WHICH NEXT EXTENDED
		;RIB EXISTS
	SUBTTL	TABLES DRIVING DEVICE DEPENDENT I/O ;⊗ DVCTAB DVCTBL IOTTAB DODATO DODATI DOCONI DOCONO DOCNSO IOTTBL


;TABLE GIVING DEVICE CODES OF CONTROLLERS THAT WE CAN TALK TO.
;TABLE IS ORDERED (HOPEFULLY) SO THAT WE WILL FIND THE FILE IN THE
;LEAST DISK ACCESSES.
;FORMAT IS:
;	XWD	<OFFSET INTO TYPE TABLES>,<DEVICE CODE>⊗-2

DEFINE	DCODE(CODE,OFS,FTS),<
	IFN	FTS,<
	XWD	OFS,CODE⊗-2
	>
>

DVCTAB:	DCODE	(540,R20OFS,FTKL10)	;RH20 0 ON KL
	DCODE	(544,R20OFS,FTKL10)	;RH20 1 ON KL
	DCODE	(550,R20OFS,FTKL10)	;RH20 2 ON KL
	DCODE	(554,R20OFS,FTKL10)	;RH20 3 ON KL
	DCODE	(270,R10OFS,FTKI10!FTKL10) ;RH10 0 ON KI OR KL
	DCODE	(274,R10OFS,FTKI10!FTKL10) ;RH10 1 ON KI OR KL
	DCODE	(560,R20OFS,FTKL10)	;RH20 4 ON KL
	DCODE	(564,R20OFS,FTKL10)	;RH20 5 ON KL
	DCODE	(570,R20OFS,FTKL10)	;RH20 6 ON KL
	DCODE	(574,R20OFS,FTKL10)	;RH20 7 ON KL
	DCODE	(360,R10OFS,FTKI10!FTKL10) ;RH10 2 ON KI OR KL
	DCODE	(364,R10OFS,FTKI10!FTKL10) ;RH10 3 ON KI OR KL
	DCODE	(<1⊗2>,R11OFS,FTKS10)	;RH11 UBA 1 ON KS
DVCTBL←←.-DVCTAB


;TABLE OF I/O INSTRUCTIONS.  DEVICE CODES FILLED IN BEFORE USE.

IOTTAB:
IFN FTKI10!FTKL10,<
DODATO:	DATAO	0,T1
DODATI:	DATAI	0,T1
DOCONI:	CONI	0,T1
DOCONO:	CONO	0,(T1)
DOCNSO:	CONSO	0,(T1)
>;END IFN FTKI10!FTKL10
IOTTBL←←.-IOTTAB
;THE FOLLOWING TABLES GIVE THE DISPATCH ADDRESSES FOR THE CONTROLLER ;⊗ OFS REDTAB WRTTAB
;DEPENDENT READ AND WRITE ROUTINES.  ALL ARE CALLED WITH THE FOLLOWING
;AC'S SETUP:
;
; J = INDEX INTO DEVICE CODE TABLE
; U = PHYSICAL UNIT NUMBER
; W = OFFSET INTO TABLES BELOW
; R = PHYSICAL MEMORY ADDRESS OF START OF TRANSFER
; LB = BLOCK ON UNIT OF FIRST BLOCK TO TRANSFER
; M = NUMBER OF CONTIGUOUS BLOCKS TO TRANSFER
;
;ALL CONTROLLER DEPENDENT ROUTINES MUST PRESERVE LB AND R WITH
;A CALL TO SAVFR.
;
;**** THE RH10 AND RH20 ENTRIES IN THE FOLLOWING TABLES MUST BE
;**** THE FIRST AND SECOND ENTRIES IN THE TABLES AND MUST REMAIN
;**** IN THE SAME RELATIVE ORDER.


DEFINE	DADDR(ADDR,OFS,FTS),<
	IFN	FTS,<
	OFS←←.-REDTAB
	EXP	ADDR
	>
>


;TABLE OF ADDRESSES OF CONTROLLER READ ROUTINES INDEXED BY CONTROLLER
;TYPE.

REDTAB:	DADDR	(R12RED,R10OFS,FTKI10!FTKL10)
	DADDR	(R12RED,R20OFS,FTKL10)
	DADDR	(R11RED,R11OFS,FTKS10)


DEFINE	DADDR	(ADDR,FTS),<
	IFN	FTS,<
	EXP	ADDR
	>
>


;TABLE OF ADDRESSES OF CONTROLLER WRITE ROUTINES INDEXED BY CONTROLLER
;TYPE.

WRTTAB:	DADDR	(R12WRT,FTKI10!FTKL10)
	DADDR	(R12WRT,FTKL10)
	DADDR	(R11WRT,FTKS10)
IFN FTKL10!FTKI10,< ;⊗ R12WRT R12RED R12XFR R10XFR R12XF1
	SUBTTL	RH10/RH20 DEVICE DEPENDENT ROUTINES


;ROUTINES TO READ FROM/WRITE TO A DRIVE ON AN RH10/RH20. CALL WITH THE
;STANDARD AC'S SETUP.  TRANSLATES THE DEVICE INDEPENDENT TRANSFER
;REQUEST INTO AS MANY TRANSFERS AS NECESSARY TO MAKE THE RH10/RH20 HAPPY.
;CALL:	PUSHJ	P,R12RED -OR- PUSHJ   P,R12WRT
;RETURN+1 IF I/O ERRORS
;RETURN+2 IF TRANSFER WAS SUCCESSFUL

R12WRT:	TLOA	S,(FL.IO)	;SET FLAG FOR OUTPUT
R12RED:	TLZ	S,(FL.IO)	;CLEAR FLAG FOR INPUT
	PUSHJ	P,SAVFR		;SAVE LB AND R
	PUSHJ	P,R12INI	;INITIALIZE THE RH10/RH20
	  POPJ	P,		;FAILED
R12XFR:	JUMPLE	M,CPOPJ1	;DONE WHEN TRANSFERED ALL BLOCKS
	TLNE	S,(FL.IO)	;WRITING?
	CAILE	LB,LB2HOM+LBOBAT	;YES, ON HOM OR BAT BLOCKS?
	CAIA			;NO
	HALT	.		;YES,  DON'T MAKE THINGS WORSE
	PUSHJ	P,R12CLR	;MAKE SURE THE RH10/RH20 IS CLEARED
	PUSHJ	P,R12SET	;MAKE IOWDS, TELL DRIVE WHERE TO START
IFN FTKL10,<
	JUMPE	W,R10XFR	;DIFFERENT IF RH10
	MOVSI	T1,<(DO.2ST)>(U) ;TALK TO STCR AND SPECIFIED DRIVE
	DPB	T4,[POINT 10,T1,29] ;STORE -VE BLOCKCOUNT
	JRST	R12XF1		;JOIN COMMON CODE
>
R10XFR:	MOVSI	T1,<(DO.1CR)>(U) ;TALK TO COMMAND REGISTER AND SPECIFIED DRIVE
	HRRI	T1,<BOOTWD⊗6>	;SET INITIAL CONTROL WORD ADDRESS
R12XF1:	TLNN	S,(FL.IO)	;DOING OUTPUT?
	TROA	T1,DO.XRD	;NO, SET READ FUNCTION CODE
	TRO	T1,DO.XWT	;YES, SET WRITE FUNCTION CODE
	XCT	DODATO		;START THE TRANSFER
	PUSHJ	P,R12WAT	;WAIT FOR IT TO COMPLETE
	PUSHJ	P,R12CHK	;CHECK FOR ERRORS
	  POPJ	P,		;GIVE NON-SKIP RETURN IF ERRORS OR TIMED OUT
	JRST	R12XFR		;DO MORE IF ANY BLOCKS LEFT
;ROUTINE TO SETUP THE CHANNEL COMMAND LIST FOR THIS TRANSFER AND ;⊗ R12SET R12SE1 R12SE2 R12SE3 R12SE4 R12SE5 R12SE6
;TELL THE DRIVE WHERE TO START THE TRANSFER.  CALL WITH THE STANDARD
;AC'S SETUP.
;CALL:	PUSHJ	P,R12SET
;RETURN+1 ALWAYS
;RETURNS WITH M, R, AND LB UPDATED TO REFLECT THIS TRANSFER AND
;	 T4/NEGATIVE BLOCKCOUNT FOR THIS TRANSFER

R12SET:	MOVEI	T4,0		;INITIALIZE BLOCK COUNT TO 0
IFN FTKL10,<
	JUMPE	W,R12SE2	;NO LOGOUT AREA FOR RH10'S
	HRRZ	T1,DVCTAB(J)	;GET DEVICE CODE FOR THIS DEVICE
	LSH	T1,2		;TIMES 2
	SUBI	T1,540		;COMPUTE OFFSET IN EPT OF LOGOUT AREA
	MOVE	T2,EPTADR	;GET PHYSICAL ADDRESS OF THE EPT
	ADDI	T2,R2IOWD-EPT	;ADD OFFSET TO FIRST IOWD
	TLO	T2,(RH2JMP)	;MAKE IT A JUMP WORD
	MOVEM	T2,EPT(T1)	;STORE JUMP WORD IN LOGOUT AREA
	MOVSI	T1,-<R2IOWL-1>	;MAKE AOBJN POINTER TO IOWD LIST
R12SE1:	JUMPLE	M,R12SE5	;STOP WHEN DONE ENTIRE TRANSFER
>
R12SE2:	MOVEI	T2,(M)		;ASSUME LESS THAN MAX
	CAMLE	M,[R1BCNT
		   R2BCNT](W)	;ARE WE CORRECT?
	MOVE	T2,[R1BCNT
		    R2BCNT](W)	;NO, MAKE IT THE MAX POSSIBLE IN 1 IOWD
	SUBI	M,(T2)		;DECREMENT BLOCKS REMAINING
	SUBI	T4,(T2)		;AND BLOCKS DONE
	LSH	T2,B2WLSH	;CONVERT TO WORDS
IFN FTKL10,<
	JUMPE	W,R12SE3	;GO IF RH10
	LSH	T2,=18+4	;POSITION IN IOWD
	TLO	T2,(RH2TRA)	;MAKE THE OPCODE A TRANSFER
	IOR	T2,R		;STORE PHYSICAL ADDRESS
	MOVEM	T2,R2IOWD(T1)	;STORE IN CHANNEL COMMAND LIST
	ADDI	R,R2WCNT	;INCREMENT CORE ADDRESS FOR NEXT TIME
	JRST	R12SE4		;JOIN COMMON CODE
>
R12SE3:	MOVNS	T2		;RH10'S WANT A NEGATIVE WORDCOUNT
	LSH	T2,=18		;MOVE TO LH
	XCT	DOCONI		;GET CONI FOR DRIVE
	TLNE	T1,(CI.122)	;SKIP IF 18 BIT DF10
	LSH	T2,4		;DF10C'S ONLY HAVE 14 BITS OF WORDCOUNT
	IOR	T2,R		;STORE PHYSICAL ADDRESS
	SUBI	T2,1		;AND ADDRESS-1
	MOVEM	T2,.VPAG0+BOOTWD ;STORE IOWD IN LOW CORE
	SETZM	.VPAG0+BOOTWD+1 ;INSURE IOWD TERMINATION
	ADDI	R,R1WCNT	;INCREMENT CORE ADDRESS FOR NEXT TIME
IFN FTKL10,<
	JRST	R12SE6		;DO ONLY ONE IOWD FOR AN RH10
R12SE4:	AOBJN	T1,R12SE1	;DO AS MANY AS POSSIBLE
R12SE5:	SETZM	R2IOWD(T1)	;STORE HALT IOWD TO TERMINATE LIST
>
R12SE6:	MOVE	T1,LB		;COPY BLOCK ADDRESS
	SUB	LB,T4		;UPDATE FOR AMOUNT OF THIS TRANSFER
	IDIV	T1,DRVBPC	;T1=CYLINDER, T2=REMAINDER
	HRLI	T1,<(DO.XDC)>(U) ;STORE IN DESIRED CYLINDER REGISTER
	XCT	DODATO		;TELL THE DRIVE
	IDIV	T2,DRVBPT	;T2=TRACK, T3=SECTOR
	DPB	T2,[POINT 8,T3,27] ;POSITION CORRECTLY
	MOVSI	T1,<(DO.XDS)>(U) ;TALK TO THE BLOCK ADDRESS REGISTER
	HRRI	T1,(T3)		;STORE ADDRESS
	XCT	DODATO		;TELL THE DRIVE
	POPJ	P,		;RETURN
;ROUTINE TO INITIALIZE THE RH10/RH20 FOR A TRANSFER. ;⊗ R12INI R12CHK
;CALL:	PUSHJ	P,R12INI
;RETURN+1 IF INITIALIZATION FAILED
;RETURN+2 IF SUCCESSFUL

R12INI:	XCT	DOCONI		;GET CONI IN T1
	JUMPE	T1,CPOPJ	;NO BITS MEANS IT DOESN'T EXIST
	PUSHJ	P,R12CLR	;BLAST THE RH10/RH20 INTO A KNOWN STATE
	MOVSI	T1,<(DO.XDT)>(U) ;NEED DRIVE TYPE REGISTER FOR THIS DRIVE
	PUSHJ	P,DRVTYP	;READ AND CHECK IT
	  POPJ	P,		;NO MATCH
	MOVSI	T1,<(DO.XCR)>(U) ;POINT TO DRIVE CONTROL REGISTER
	HRRI	T1,DO.XCL	;FUNCTION IS DRIVE CLEAR
	XCT	DODATO		;CLEAR THE DRIVE
	HRRI	T1,DO.XRP	;FOLLOWED BY A READIN
	XCT	DODATO		;  PRESET
	MOVSI	T1,<(DO.XSR)>(U) ;SETUP TO READ STATUS REGISTER
	PUSHJ	P,REDREG	;DO SO
	ANDI	T1,DI.XSM	;MASK, IGNORING WRITE LOCK, PGM
	CAIE	T1,DI.XSB	;IS IT OK?
	POPJ	P,		;NO
	JRST	CPOPJ1		;GIVE SKIP RETURN


;ROUTINE TO CHECK THE RH10/RH20 FOR ERRORS IN THE LAST TRANSFER.
;CALL:	PUSHJ	P,R12CHK
;RETURN+1 IF ERRORS DETECTED
;RETURN+2 IF NO ERRORS

R12CHK:	MOVSI	T1,<(DO.XSR)>(U) ;SET TO READ STATUS REGISTER
	PUSHJ	P,REDREG	;DO SO
	TRNE	T1,DI.XCE	;COMPOSITE ERROR?
	POPJ	P,		;YES, GIVE ERROR RETURN
	MOVE	T1,[CI.1ER
		    CI.2ER](W)	;GET CONI ERROR BITS FOR CONTROLLER
	XCT	DOCNSO		;ANY SET?
	JRST	CPOPJ1		;NO, GIVE SKIP RETURN
	POPJ	P,		;YES
;ROUTINE TO WAIT FOR THE RH10/RH20 TO FINISH A TRANSFER. ;⊗ R12WAT R12CLR
;CALL:	PUSHJ	P,R12WAT
;RETURN+1 IF SUCCESSFUL
;RETURN+2 IF TIMED OUT

R12WAT:	MOVSI	T2,10		;LOOP COUNT = ABOUT 7 SECONDS
	MOVE	T1,[CI.1RA!CI.XDN
		    CI.2RA!CI.XDN](W) ;WAIT FOR DONE OR RAE TO COME UP
	XCT	DOCNSO		;IN THE CONI
	SOJG	T2,.-1		;HASN'T YET, WAIT FOR IT
	JUMPLE	T2,CPOPJ1	;GIVE SKIP RETURN IF TIMED OUT
	POPJ	P,		;RETURN


;ROUTINE TO FORCE THE RH10/RH20 INTO A KNOWN STATE FOR A TRANSFER.
;CALL:	PUSHJ	P,R12CLR
;RETURN+1 ALWAYS

R12CLR:	MOVEI	T1,CO.XMI	;DO A
	XCT	DOCONO		;  MASSBUS INIT
IFN FTKL10,<
	MOVEI	T1,CO.XSX	;THEN A
	XCT	DOCONO		;  STOP TRANSFER
	MOVEI	T1,CO.XDN	;THEN A
	XCT	DOCONO		;  CLEAR DONE
	MOVEI	T1,CO.2ME	;AND FINALLY A
	XCT	DOCONO		;  MASSBUS ENABLE
>
	POPJ	P,


>;END IFN FTKL10!FTKI10
IFN FTKS10,< ;⊗ R11WRT R11RED R11XFR R11XF1
	SUBTTL	RH11 DEVICE DEPENDENT ROUTINES


;ROUTINES TO READ FROM/WRITE TO A DRIVE ON AN RH11.  CALL WITH THE
;STANDARD AC'S SETUP.  TRANSLATES DEVICE INDEPENDENT TRANSFER REQUEST
;TO AS MANY TRANSFERS AS NECESSARY TO MAKE THE RH11 HAPPY.
;CALL:	PUSHJ	P,R11RED -OR- PUSHJ	P,R11WRT
;RETURN+1 IF I/O ERRORS
;RETURN+2 IF TRANSFER WAS SUCCESSFUL

R11WRT:	TLOA	S,(FL.IO)	;SET FLAG FOR OUTPUT
R11RED:	TLZ	S,(FL.IO)	;CLEAR FLAG FOR INPUT
	PUSHJ	P,SAVFR		;SAVE LB AND R
	HRLZ	T4,DVCTAB(J)	;SET T4=UBA,,0
	PUSHJ	P,R11INI	;INITIALIZE THE RH11
	  POPJ	P,		;FAILED
R11XFR:	JUMPLE	M,CPOPJ1	;DONE WHEN TRANSFERED ALL BLOCKS
	TLNE	S,(FL.IO)	;WRITING?
	CAILE	LB,LB2HOM+LBOBAT ;YES, ON HOM OR BAT BLOCKS?
	CAIA			;NO
	HALT	.		;YES, DON'T MAKE THINGS WORSE
	PUSHJ	P,R11CLR	;CLEAR THE RH11
	WRIO	U,SO.CS2(T4)	;SELECT DRIVE
	PUSH	P,T4		;SAVE T4
	PUSHJ	P,R11SET	;SET UBA MAP SLOTS, DRIVE LBN
	POP	P,T4		;RESTORE T4
	MOVEI	T1,SO.WRT	;ASSUME WRITING
	TLNN	S,(FL.IO)	;ARE WE CORRECT?
	MOVEI	T1,SO.RED	;NO, SET READING
	WRIO	T1,SO.CS1(T4)	;START THE TRANSFER
	MOVSI	T2,2		;LOOP COUNT
R11XF1:	RDIO	T1,SO.CS1(T4)	;READ STATUS REGISTER
	TRNN	T1,SI.RDY	;READY COME UP?
	SOJG	T2,R11XF1	;NO, LOOP
	JUMPLE	T2,CPOPJ	;ERROR RETURN IF TIMED OUT
	TRNE	T1,SI.S1E	;ERRORS?
	POPJ	P,		;YES
	JRST	R11XFR		;DO MORE IF ANY BLOCKS LEFT
;ROUTINE TO SETUP THE UBA MAPPING REGISTERS, AND THE DRIVE REGISTERS ;⊗ R11SET R11SE1
;FOR THIS TRANSFER.  CALL WITH THE STANDARD AC'S SETUP.
;CALL:
;	T4/UBA,,0
;	PUSHJ	P,R11SET
;RETURN+1 ALWAYS
;RETURNS WITH M, R, AND LB UPDATED TO REFLECT THIS TRANSFER.
;DESTROYS T4

R11SET:	MOVEI	T1,(R)		;GET ADDRESS OF FIRST WORD TO TRANSFER
	ANDI	T1,PAGSIZ-1	;ISOLATE OFFSET OF FIRST WORD IN PAGE
	LSH	T1,2		;MAKE IT A BYTE OFFSET
	WRIO	T1,SO.BA(T4)	;SET THE BUS ADDRESS REGISTER
	MOVE	T1,LB		;COPY LBN OF FIRST BLOCK TO TRANSFER
	IDIV	T1,DRVBPC	;T1=CYLINDER, T2=BLOCK IN CYLINDER
	WRIO	T1,SO.DC(T4)	;SET DESIRED CYLINDER REGISTER
	IDIV	T2,DRVBPT	;T2=TRACK, T3=BLOCK IN TRACK
	DPB	T2,[POINT 8,T3,27] ;POSITION TRACK NUMBER
	WRIO	T3,SO.DA(T4)	;TELL DRIVE
	MOVEI	T1,(M)		;ASSUME WE CAN DO ALL OF TRANSFER
	CAILE	T1,RSBCNT	;LARGER THAN MAX?
	MOVEI	T1,RSBCNT	;YES, USE MAX
	SUBI	M,(T1)		;ADJUST M FOR NEXT TIME
	ADDI	LB,(T1)		;ADVANCE TO FIRST BLOCK OF NEXT TRANSFER
	MOVE	T2,R		;COPY CORE ADDRESS OF FIRST WORD
	LSH	T1,B2WLSH	;COMPUTE WORD COUNT
	ADD	R,T1		;ADVANCE CORE ADDRESS FOR NEXT TIME
	LSH	T1,1		;COMPUTE PDP11 WORD COUNT
	MOVNS	T1		;MAKE IT NEGATIVE
	WRIO	T1,SO.WC(T4)	;SET WORD COUNT REGISTER
	LSH	T2,W2PLSH	;COMPUTE PAGE NUMBER OF 1ST PAGE
	MOVE	T1,R		;GET ADDRESS OF FIRST WORD OF NEXT TRANSFER
	SUBI	T1,1		;MAKE IT LAST ADDRESS OF THIS TRANSFER
	LSH	T1,W2PLSH	;COMPUTE PAGE NUMBER
	SUBI	T1,-1(T2)	;COMPUTE NUMBER OF PAGES TO MAP
	MOVNS	T1		;MAKE IT NEGATIVE
	HRL	T2,T1		;AND MAKE AN AOBJN POINTER
	TRO	T2,SO.VFT	;SET VALID AND FAST TRANSFER
R11SE1:	WRIO	T2,SO.UPR(T4)	;MAP ONE PAGE
	ADDI	T4,1		;INCREMENT UBA MAP ADDRESS
	AOBJN	T2,R11SE1	;LOOP FOR ALL
	POPJ	P,		;RETURN
;ROUTINE TO INITIALIZE THE RH11 FOR A TRANSFER. ;⊗ R11INI R11CLR
;CALL:
;	T4/UBA,,0
;	PUSHJ	P,R11INI
;RETURN+1 IF INITIALIZATION FAILED
;RETURN+2 IF SUCCESSFUL

R11INI:	RDIO	T1,SO.USR(T4)	;READ UBA STATUS REGISTER
	TRNE	T1,SI.UER	;ANY ERRORS?
	POPJ	P,		;YES, ERROR
	PUSHJ	P,R11CLR	;CLEAR THE RH11
	WRIO	U,SO.CS2(T4)	;SELECT DRIVE
	RDIO	T1,SI.DT(T4)	;READ DRIVE TYPE REGISTER
	PUSHJ	P,DRVTYP	;CHECK IT
	  POPJ	P,		;FAILED
	MOVEI	T1,SO.DCL	;GET DRIVE CLEAR FUNCTION
	WRIO	T1,SO.CS1(T4)	;DO IT
	MOVEI	T1,SO.RIP	;GET READIN PRESET FUNCTION
	WRIO	T1,SO.CS1(T4)	;DO IT
	RDIO	T1,SO.DS(T4)	;READ DRIVE STATUS REGISTER
	ANDI	T1,SO.DSM	;MASK, IGNORING WRITE LOCK, PGM
	CAIE	T1,SO.DSB	;IS IT OK?
	POPJ	P,		;NO
	JRST	CPOPJ1		;GIVE SKIP RETURN


;ROUTINE TO FORCE THE RH11 INTO A KNOWN STATE.
;CALL:
;	T4/UBA,,0
;	PUSHJ	P,R11CLR
;RETURN+1 ALWAYS

R11CLR:	MOVEI	T1,SO.UBI	;UBA INIT
	WRIO	T1,SO.USR(T4)	;CLEAR THE UBA/DRIVES
	POPJ	P,		;RETURN


>;END IFN FTKS10

>;IFN 0 (from BOOT10)
;FF

LIT
VAR
FF←←.

IFN DSKDSW,<
IFE DEBSW,<
	END DSKDMP
>;IFE DEBSW
IFN DEBSW,<
	END 300
>;DEBSW
>;DSKDSW

IFE DSKDSW,<
IFE KLBOOT,<
IFN DEBSW,<
	END BOOT
>;DEBSW
IFE DEBSW,<
	END PNCHGO
>;IFE DEBSW
>;IFE KLBOOT
IFN KLBOOT,<
	END BOOT
>;KLBOOT
>;IFE DSKDSW